So i am trying to upload multiple files at once, but each time i do it is only uploading the last file in the loop for each file upload that i try to do. Ultimately it is only uploading one file to my server that multiple points in my database are referencing.
I have tried executing the upload file function outside of the loop with independent functions and variables but it is still doing it.
My code:
<?php $image_number = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$image_allowed = array('jpg', 'jpeg', 'gif', 'png');
if (empty($errors) === true) {
foreach ($image_number as $value) {
if (isset($_FILES['story_image_' . $value]) === true) {
if (empty($_FILES['story_image_' . $value]['name']) === false) {
if (in_array(strtolower(end(explode('.', $_FILES['story_image_' . $value]['name']))), $image_allowed) === false) {
$errors[] = 'Incorrect file type for \'Story image ' . $value . '\'. Allowed file types: ' . implode(', ', $image_allowed);
} else if ($_FILES['story_image_' . $value]['size'] > 1048576) {
$errors[] = 'Story image ' . $value . '\'s file size may not exceed 1 MB, or 1048576 Bytes.';
}
}
}
}
}
foreach ($image_number as $value) {
if ($_POST['removeImage' . $value] === 'on') {
remove_story_image($story_data['story_id'], $value, $story_data['story_image_' . $value]);
} else {
if (isset($_FILES['story_image_' . $value]) === true) {
if (empty($_FILES['story_image_' . $value]['name']) === false) {
$file_path = '/cdsite/images/storyimages/' . substr(md5(time()), 0, 10) . '.' . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
$movefile_path = $_SERVER['DOCUMENT_ROOT']."/cdsite/images/storyimages/" . substr(md5(time()), 0, 10) . "." . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
move_uploaded_file($_FILES['story_image_' . $value]['tmp_name'], $movefile_path);
mysql_query("UPDATE `stories` SET `story_image_" . $value . "` = '" . mysql_real_escape_string($file_path) . "' WHERE `story_id` = " . $story_data['story_id']);
}
}
}
}
?>
I have checked my form, and all of the file fields' names that are independently named and match. It is not a syntax issue because the first loop checking for errors works flawlessly. its only when i try to upload the file does it start to overwrite.
Can anyone enlighten me? ( i am a pretty big noob so please try to keep it in newb speak)
***** Update ***********
So I have solved the problem now and below is the working code:
foreach ($image_number as $value) {
if ($_POST['removeImage' . $value] === 'on') {
remove_story_image($story_data['story_id'], $value, $story_data['story_image_' . $value]);
} else {
if (isset($_FILES['story_image_' . $value]) === true) {
if (empty($_FILES['story_image_' . $value]['name']) === false) {
$file_path = '/cdsite/images/storyimages/' . substr(md5(time()), 0, 10) . '.' . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
$movefile_path = $_SERVER['DOCUMENT_ROOT']."/cdsite/images/storyimages/" . substr(md5(time()), 0, 10) . "." . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
if (file_exists($movefile_path) === true) {
$file_path = '/cdsite/images/storyimages/' . substr(md5(time()), 0, 10) . substr(md5(rand()),0,10) . '.' . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
$movefile_path = $_SERVER['DOCUMENT_ROOT'].$file_path;
}
move_uploaded_file($_FILES['story_image_' . $value]['tmp_name'], $movefile_path);
mysql_query("UPDATE `stories` SET `story_image_" . $value . "` = '" . mysql_real_escape_string($file_path) . "' WHERE `story_id` = " . $story_data['story_id']);
}
}
}
}
For those who may run into a similar problem in the future and need a simple explanation, which i so often appreciate when others provide one, here is a brief explanation of what the issue was and how i fixed it.
The problem was i was md5 hashing the same time when i was iterating through the loop, rewriting over the same file name with this line of code:
$movefile_path = $_SERVER['DOCUMENT_ROOT']."/cdsite/images/storyimages/" . substr(md5(time()), 0, 10) . "." . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
As you notice i have two file paths. This isn't to confuse anyone, it is to allow me to upload a absolute path to the database that html can reference later ($file_path) and to have an absolute path that php can work with to upload the file ($movefile_path).
To fix the problem i had the loop check to see if the file already exists and, if it did, just added a random string that was md5 hashed following the md5 hashed timestamp to make a new unique file name. I used the $movefile_path file path to check to see if the file existed because that is the path php can use.
I also made sure to include the updated $file_path variable in the updated $movefile_path, otherwise re-hashing the random string would have given me a different file name for html to reference from my database than the actual file name that php uploaded.
You should rename the file you are uploading, never trust user input...
You could put a unix timestamp or unique id behind the image name
Related
I am trying to upload a tmp file and then copy it. But it is not appearing in the second folder, is there an overlay or something I have to watch?
$uploadPath = '/.../..../image/';
$uploadPathpreview = '/.../..../blog/';
if ($counter == 0){
$preview_file = $uploadPath . DS . 'preview_' . date("Ymd-Hi-") . $img_name;
$preview_file_save = $uploadPathpreview . DS . 'preview_' . date("Ymd-Hi-") . $img_name;
if(move_uploaded_file($tmp_name, $preview_file)){
$tmp = $preview_file;
$new = $preview_file_save;
}
copy($tmp,$new);
The file in image exists by the way. And I tried it without the if()
Currently I am working on a media uploader system.
When a user uploads files, I wanted the system to automatically check whether this file already exists, and if so, add a (x) to the basename.
DSC_2193.jpg would become DSC_2193 (1).jpg
DSC_2193 (2).jpg would become DSC_2193 (3).jpg
So I came up with the following function:
<?php
private function setFileName($path)
{
if (file_exists($path)) {
$file = pathinfo($path);
if (preg_match('/\(([0-9]+)\).' . $file['extension'] . '/', $file['basename'], $matches)) {
return $this->setFileName($file['dirname'] . '/' . preg_replace_callback('/\(([0-9]+)\).' . $file['extension'] . '/', function($matches)
{
return '(' . ($matches[1] + 1) . ')';
}, $file['basename']) . '.' . $file['extension']);
} else {
$basename = substr(basename($path, $file['extension']), 0, -1);
$basename .= ' (1).' . $file['extension'];
return $this->setFileName($file['dirname'] . '/' . $basename);
}
}
else
return $path;
}
?>
Now I was wondering: would this be the right approach to achieve this? If not: maybe someone can come up with a better alternative. If it is the most efficient way, maybe someone benefits from this.
You can do it easily using while cycle. Here is simple scratch:
private function setFileName($path)
{
$file = pathinfo($path);
if (file_exists($path)) {
$i = 1;
while (file_exists($file['filename'] . ' (' . $i . ').' . $file['extension'])) $i++;
$filename = $file['filename'] . ' (' . $i . ').' . $file['extension']; // don't know if you want also directory path
}
else
$filename = $file['filename'] . '.' . $file['extension'];
// some code to rename/move_uploaded_file...
}
I don't know what you want then if you have $filename set (move_uploaded_file, or just return $filename), so the rest of code is up to you.
I'm trying to rename all files in a folder, I want the last character before the extension to be removed.
This is the code I'm using:
$sql = 'SELECT * FROM tblphotoseries WHERE photoSerieID = ' . mysql_real_escape_string($photoSerieID) . ' AND FKuID = ' . $_SESSION['uID'];
if($series = GetFromDB($sql)){
foreach ($series as $serie){
$path = '../uploads/' . $serie["FKcatID"] . '/' . $_SESSION['uCode'] . '/' . $serie["seriesCode"] . '';
}
$files = scandir($path);
foreach($files as $file) {
if($file != ".." && $file != "."){
$new_name = explode(".", $file);
$ext = $new_name[1];
$new_name = $new_name[0];
$new_name[strlen($new_name) - 1] = "";
$new_name = $new_name . "." . $ext;
$new_name = (string)$new_name;
echo $file . " -> " . $new_name . "\n\r";
clearstatcache();
if(file_exists($path . '/' . $file)){
echo "file_exists \n\r";
clearstatcache();
if(rename($path . '/' . $file, $path . '/' . $new_name)){
echo "rename successful \n\r";
}else{
echo "rename failed \n\r";
}
}
}
}
}
This outputs the following:
AA04a_.jpg -> AA04a.jpg
file_exists
rename failed
AA04b_.png -> AA04b.png
file_exists
rename failed
AA04c_.png -> AA04c.png
file_exists
rename failed
Can anyone spot what's going wrong here? Privileges are ok, I've tried chmod 0777 on the file before renaming as well, without success.
Thanks,
Rik
SOLVED:
$new_name[strlen($new_name) - 1] = "";
had to be replaced by
$new_name = substr_replace($new_name, '', strlen($new_name) - 1, 1);
I this PHP code:
<?php
// Check for errors
if($_FILES['file_upload']['error'] > 0){
die('An error ocurred when uploading.');
}
if(!getimagesize($_FILES['file_upload']['tmp_name'])){
die('Please ensure you are uploading an image.');
}
// Check filesize
if($_FILES['file_upload']['size'] > 500000){
die('File uploaded exceeds maximum upload size.');
}
// Check if the file exists
if(file_exists('upload/' . $_FILES['file_upload']['name'])){
die('File with that name already exists.');
}
// Upload file
if(!move_uploaded_file($_FILES['file_upload']['tmp_name'], 'upload/' . $_FILES['file_upload']['name'])){
die('Error uploading file - check destination is writeable.');
}
die('File uploaded successfully.');
?>
and I need to act like a "windows" kind of treatment for existing files - I mean the if the file exists, i want it to be changed to the name of the file with the number 1 after it.
for example: myfile.jpg is already exists, so if you'll upload it again it will be myfile1.jpg, and if myfile1.jpg exists, it will be myfile11.jpg and so on...
how can i do it? i tried some loops but unfortunately without success.
You could do something like this:
$name = pathinfo($_FILES['file_upload']['name'], PATHINFO_FILENAME);
$extension = pathinfo($_FILES['file_upload']['name'], PATHINFO_EXTENSION);
// add a suffix of '1' to the file name until it no longer conflicts
while(file_exists($name . '.' . $extension)) {
$name .= '1';
}
$basename = $name . '.' . $extension;
To avoid very long names, it would probably be neater to append a number, e.g. file1.jpg, file2.jpg etc:
$name = pathinfo($_FILES['file_upload']['name'], PATHINFO_FILENAME);
$extension = pathinfo($_FILES['file_upload']['name'], PATHINFO_EXTENSION);
$increment = ''; //start with no suffix
while(file_exists($name . $increment . '.' . $extension)) {
$increment++;
}
$basename = $name . $increment . '.' . $extension;
You uploaded a file called demo.png.
You tried to upload the same file demo.png and it got renamed to demo2.png.
When you try to upload demo.png for 3rd time, it gets renamed to demo1.png once again and replaces the file you upload in (2).
so you won't find demo3.png
For user6930268;
i think your code should be:
$name = pathinfo($_FILES['file_upload']['name'], PATHINFO_FILENAME);
$extension = pathinfo($_FILES['file_upload']['name'], PATHINFO_EXTENSION);
$dirname = pathinfo($_FILES['file_upload']['name'], PATHINFO_DIRNAME);
$dirname = $dirname. "/";
$increment = ''; //start with no suffix
while(file_exists($dirname . $name . $increment . '.' . $extension)) {
$increment++;
}
$basename = $name . $increment . '.' . $extension;
$resultFilePath = $dirname . $name . $increment . '.' . $extension);
Here is a my function i'm using. It will generate file (1).txt , file (2).txt , file ...
function getFilePathUnique($path) {
while ($this->location->fileExists($path)) {
$info = pathInfo($path);
//extract the current number of file
preg_match("/\([0-9]+\)$/",$info["filename"], $number);
$number = str_replace(["(" , ")"] , ["" , ""] , $number[0]);
//remove the old number
$info["filename"] = trim(preg_replace( "/\([0-9]+\)$/" , "" , $info["filename"] ));
//append new number
$info["filename"] .= " (" . (++$number) . ")";
//build path
$path = ($info["dirname"] != "." ? $info["dirname"]: "" ).
$info["filename"] . "." . $info["extension"];
}
return $path;
}
I'm currently getting to know more with uploadify, which by the way is what I'm using on my Wordpress plugin. I got the uploading of file correctly; it's job is to upload single .pdf files only. When I tried uploading the same file twice and checked the folder where the uploaded files will be stored, I only have a single file. I guess it's being overwritten knowing the file already exists on the folder. What bugs me is that how will I change the filename of the second uploaded file(the same file) such that it will result into 'filename(2)', 'filename(3)' and so on.
Here's my code, enlighten me on where should I start configuring on my uploadify.php:
if (!empty($_FILES)) {
$name = $_FILES['Filedata']['name'];
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $targetFolder;
$targetFile = rtrim($targetPath,'/') . '/' . $_FILES['Filedata']['name'];
$path = pathinfo($targetFile);
$newTargetFile = $targetFolder.$name;
// Validate the file type
$fileTypes = array('pdf'); // File extensions
$fileParts = pathinfo($_FILES['Filedata']['name']);
if (in_array($fileParts['extension'],$fileTypes)) {
// i think somewhere here , will i put something, but what's that something?
move_uploaded_file($tempFile,$newTargetFile);
echo $newTargetFile;
} else {
echo 'Invalid file type.';
}
return $newTargetFile;
}
Change this:
$newTargetFile = $targetFolder.$name;
To this:
$i = 2;
list( $filename, $ext) = explode( '.', $name);
$newTargetFile = $targetFolder . $filename . '.' . $ext;
while( file_exists( $newTargetFile)) {
$newTargetFile = $targetFolder . $filename . '(' . ++$i . ')' . '.' . $ext;
}
Try this:
<?php
function get_dup_file_name($file_name) {
$suffix = 0;
while (file_exists($file_name . ($suffix == 0 ? "" : "(" . $suffix . ")"))) {
$suffix++;
}
return $file_name . ($suffix == 0 ? "" : "(" . $suffix . ")");
}
?>