I am working on an application, where the user has to upload files in a cart.e.g. the user upload the file "A" and now doing different work. After some time he again upload another file, file "B". How I can manage the file path or store the file path, as if I use move_uploaded_file() function, then it can overwrite the other user's file with same file name.
Thanks.
When I've had this issue, I have used a timestamp added to the filename. Usually I want to cleanse the filename anyway, so I
replace characters I don't like
remove the file extension and check it looks OK (e.g. pdf not exe)
add a timestamp to the filename
put the extension back on
Obviously, this isn't suitable in every instance, but it might give you some ideas.
Create folder run time against session id, that way only current session user files goes to the folder.
temp_uploads/ (main uploads folder)
temp_uploads/_jhk43543h5h435k3453 (session id folder for user 1)
temp_uploads/_jhk43543h5h435k34tr (session id folder for user 2)
temp_uploads/_jhk43543h5h43trtrtg (session id folder for user 3)
you just need store session id for each user, which you maybe you are already doing.
happy Coding :)
You use php's time function to generate a timestamp that you append to the filename so that they can be different. Then you can use a column in the db to store the file paths. You could store all the file paths in the same column but separate each one with ; or any other character. To get the separate paths, you can use php's explode function.
Related
I don't want to read file using tmp_name. Is there any other possible methods to read file from a folder with its original name that I stored in databases?
Also, I am trying to access contents of that file in second form.
All else being equal: No.
A file was uploaded and it was saved to a temporary place with a generated filename and your PHP program was told what filename the client said it should have. The two filenames are not the same.
You can't access it using its original file name because that isn't the file name it has on the computer running the PHP.
The script handling the upload could use move_uploaded_file to move the file to somewhere else and change its name so it is the same as the one the client told you it originally had. Then you would be able to use that name. You would, of course, have to be careful to avoid collisions. Two different files with the same name could be uploaded.
I have a PHP file that has a $_FILES variable in it, and I obviously have a temp file of the file uploaded saved. Problem is that what I want to do is let the user upload the image, validate that it's okay (both via 1st php file), and then allow the user to enter info about the image. From the info I can obtain the name of the image and use move_uploaded_file() to save the image (on the second PHP). The problem is that the file uploaded to the temp file is, well, temporary, and so I can't use it in my second PHP file. Is there any way to go around that? I can move_uploaded_file() in the first file but I'm looking for something easier. I still want it to be like a temp folder in the sense that the file is temporary, but I want to keep it for a couple of minutes after the execution of the first PHP file...
Thanks.
The first page - the one that accepts the file - will need to use move_uploaded_file(). You cannot escape this requirement.
However, you can use tempnam() to create a new temporary filename and use move_uploaded_file() to copy the file to that name. Then pass that second filename to the second page so it knows where it is.
The other alternative is to collapse all the input and processing into one POST, so that all the information is entered at the same time the file is uploaded. This approach has always worked for me.
I have a topic/question concerning your upload filename standards, if any, that you are using. Imagine you have an application that allows many types of documents to be uploaded to your server and placed into a directory. Perhaps the same document could even be uploaded twice. Usually, you have to make some kind of unique filename adjustment when saving the document. Assume it is saved in a directory, not saved directly into a database. Of course, the Meta Data would probably need to be saved into the database. Perhaps the typical PHP upload methods could be the application used; simple enough to do.
Possible Filenaming Standard:
1.) Append the document filename with a unique id: image.png changed to image_20110924_ahd74vdjd3.png
2.) Perhaps use a UUID/GUID and store the actual file type (meta) in a database: 2dea72e0-a341-11e0-bdc3-721d3cd780fb
3.) Perhaps a combination: image_2dea72e0-a341-11e0-bdc3-721d3cd780fb.png
Can you recommend a good standard approach?
Thanks, Jeff
I always just hash the file using md5() or sha1() and use that as a filename.
E.g.
3059e384f1edbacc3a66e35d8a4b88e5.ext
And I would save the original filename in the database may I ever need it.
This will make the filename unique AND it makes sure you don't have the same file multiple times on your server (since they would have the same hash).
EDIT
As you can see I had some discussion with zerkms about my solution and he raised some valid points.
I would always serve the file through PHP instead of letting user download them directly.
This has some advantages:
I would add records into the database if users upload a file. This would contain the user who uploaded the file, the original filename and tha hash of the file.
If a user wants to delete a file you just delete the record of the user with that file.
If no more users has the file after delete you can delete the file itself (or keep it anyway).
You should not keep the files somewhere in the document root, but rather somewhere else where it isn't accessible by the public and serve the file using PHP to the user.
A disadvantage as zerkms has pointed out is that serving files through PHP is more resource consuming, although I find the advantages to be worth the extra resources.
Another thing zerkms has pointed out is that the extension isn't really needed when saving the file as hash (since it already is in the database), but I always like to know what kind of files are in the directory by simply doing a ls -la for example. However again it isn't really necessarily.
I have a form where an admin will upload three pictures with different dimensions to three different designated directories. now to make sure that i don't get into the problem of duplicate file names i implemented something like the php will compare the uploaded file name and it will check if that file name exist in the designated directory if yes then it will echo an error and stop the script execution.
Now one of my friend suggested me that it is very bad asking the admin to manually rename the picture file and asking them to take care of the file duplication problem. the solution he suggested was to rename the file automatically and then store it in the database and then direct it to directory.
I am confused about what combination should i give to the renamed file and also make sure it will remain unique file name to be more precise i would like you to understand my directory structure
as i said there will be three pictures files the admin will be uploading namely
a) Title Picture b) Brief Picture c)
Detail Picture
and all the three picture files will be moved to the different respective directory, like title picture goes to title directory and so on.
i am using to script below currently just to move and store the file name with path using varchar in the database.
$ns_pic_title_loc= $_FILES["ns_pic_title"]["tmp_name"];
$ns_pic_title_name = $_FILES["ns_pic_title"]["name"];
move_uploaded_file($ns_pic_title_loc, $ns_title_target.$ns_pic_title_name) or die(mysql_error());
that is just the sample code i havent included the validation function which i am using. i was thinking like i want to rename all the files like
a) In title directory the file should be stored as.
title_1.jpg
title_2.jpg
title_3.jpg
title_4.jpg
and so on
and the same way to rest of the pictures. how do i do that? what function do i use to achieve my target. and if this is not the good way to rename the file i would appreciate any suggestion followed to rename the file.
thanks in advance
Well, here's a possible solution:
Get uploaded filename from $_FILES["ns_pic_title"]["name"] and separate extension OR if we are only talking about image files get the image type with getimagesize($_FILES["ns_pic_title"]["tmp_name"]);
Check your database for the maximum id of the image records and make the the $file_name variable 'title_'.($max_id + 1)
At this point you should have $file_name and $file_extension so do move_uploaded_file($_FILES["ns_pic_title"]["tmp_name"], $ns_title_target.$file_name.'.'.$file_extension)
Hopefully this makes sense and helps.
There are a couple of good options with various pros and cons.
Use php's tempnam when moving the file, and store the path in your mysql database. tempnam generates a unique filename.
Use mysql to store the image content in a blob. This way you will access the image content via an id instead of a pathname.
Instead of having logic to figure out what the latest picture name is and calculate the next number increment, why not just use PHP's tempnam() function? It generates an unique name with a prefix of your choice (i.e., "title", "brief", "detail"). You could also simply prepend a timestamp to the file name -- if you don't have a whole lot of admins uploading pictures at the same time, that should handle most name conflicts.
Since your pictures are going to be sorted into title, brief and detail directories already, it's not really necessary to name each picture title_*, brief_*, and detail_*, right? If it's in the title directory, then it's obviously a title picture.
Also, you're going to be putting the file names in the database. Then elsewhere in the app, when you want to display a picture, I assume you are getting the correct file name from the database. So it isn't really important what the actual file name is as long as the application knows where to find it. If that's correct, it's not necessary to have a very friendly name, thus a tempnam() file name or a timestamp plus the original file name would be acceptable.
Because you are storing references into the DB, I would prefer to just md5 the datetime and use that for the filename and store the disk filename to the DB also. It doesn't matter what name it is written to disk with as long as you can point to it with the unique name into the DB.
I use this methodology, and in none of my testing does the disk name (md5 from the datetime) ever require multiple tries.
I am currently using the Zend Framework and have an upload file form. An authenticated user has the ability to upload a file, which will be stored in a directory in the application, and the location stored in the database. That way it can be displayed as a file that can be downloaded.
Download
But something I am noticing is that a file with the same name will overwrite a file in the uploads directory. There is no error message, nor does the filename increment. So I think the file must be overwritten (or never uploaded).
What are some best practices I should be aware of when uploading, moving, or storing these files? Should I always be renaming the files so that the filename is always unique?
Generally, we don't store files with the name given by the user, but using a name that we (i.e. our application) chosse.
For instance, if a user uploads my_file.pdf, we would :
store a line in the DB, containing :
id ; an autoincrement, the primary key -- "123", for instance
the name given by the user ; so we can send the right name when someone tries to download the file
the content-type of the file ; application/pdf or something like that, for instance.
"our" name : file-123 for instance
when there is a request to the file with id=123, we know which physical file should be fetched ('file-' . $id) and sent.
and we can set some header to send to correct "logical" name to the browser, using the name we stored in the DB, for the "save as" dialog box
same for the content-type, btw
This way, we make sure :
that no file has any "wrong" name, as we are the ones choosing it, and not the client
that there is no overwritting : as our filenames include the primary key of our table, those file names are unique
Continuing on Pascal MARTIN's answer:
If using an id as name you can also come up with a directory naming strategy. I takes no longer to get /somedir/part1ofID/part2OfID from the filesystem than /somedir/theWholeID but it will let you choose how many files are stored in the same directory from how you split the ID to form the path and file name.
The next good thing is that the script that you use to actually output the file to the user can choose if the user is authorized to see the file or not. This of course requires the files to be stored somewhere not readable by everyone by default.
You may also want to look at this other question. Not totally related, but good to be aware of.
Yes you need to come up with a way to name them uniquely. Ive seen all kinds of different strategies for this ranging from a hash base on the orignal filename, pk of the db record and upload timestamp, to some type of slugging, again based on varous fields in the db record its attached to or related records.