Renaming a file before uploading to server - php

I'm trying to create some sort of "selfie" uploader on mobile phones. Now it's working great it's just that when i test the upload file on my iPhone all the photo's will be named image.jpeg so they keep overwriting each other. Now what i want to do is rename the file to let's say image1.jpeg and the next image2.jpeg before it gets uploaded to the server.
My current code:
<?php
if (isset($_FILES['myFile'])) {
move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile'] ['name']);
echo 'successful';
}
?>
I tried this code to give my image a filename value of image plus a random number between 1 and 99999 but this wasn't a succes.
<?php
if (isset($_FILES['myFile'])) {
$temp = explode(".",$_FILES["myFile"]["name"]);
$newfilename = rand(1,99999) . '.' .end($temp);
move_uploaded_file($_FILES["myFile"]["tmp_name"], "uploads/" . $newfilename;
echo 'successful';
}
?>
Any pointers will be appreciated.

this wasn't a succes.
Not a descriptive way to describe your error. Please include PHP errors or investigate them yourself so you (or we) can figure out what problems you're having with your code. Some editors will even tell you where your parsing errors are. You can also use a PHP linter.
The error lies in this line:
move_uploaded_file($_FILES["myFile"]["tmp_name"], "uploads/" . $newfilename;
The move_uploaded_file function is missing a closing bracket, so you must put it back in:
move_uploaded_file($_FILES["myFile"]["tmp_name"], "uploads/" . $newfilename);
I'd also recommend a better random filename generator. Try something like this instead:
$newfilename = sha1(uniqid(mt_rand(), true)) . '.' .end($temp);
It will create a hash that has a much lower likelihood of collisions (read: 1 in 2160.)
Best of luck!

I think your approach is not quite correct.
Renaming the file at client end assumes that each client will have a unique file naming convention. However, in practice this would be impossible, if not very difficult to implement.
You can however, much more easily change the file naming convention on the server.
<?php
if (isset($_FILES['myFile'])) {
$userid = 1; // User id loaded from database or some other way to identify user
$temp = explode(".",$_FILES["myFile"]["name"]);
// Create a distinct name for the file
$newfilename = $userid . '.' . date_timestamp_get() '.' .end($temp);
move_uploaded_file($_FILES["myFile"]["tmp_name"], "uploads/" . $newfilename);
echo 'successful';
}
?>
The above code, rather than using a random number generator, ensure a unique key based on the user's id, and the current timestamp, along with the filename. Other variations such as GUID could also be used.

Related

PHP MD5 File Name

I have an upload script, and to fix the upload for several things, I want to md5 encrypt the files name. Here is the top of the php script I am using.
$target_dir = "file_dir/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
I attempted to use the md5() method like this
md5($target_dir . basename($_FILES["fileToUpload"]["name"]));
which did not work. Just came back as an error.
If you guys need more code in this script to help me, please tell me in the comments and i'll make a dummy copy of my script. Thank's in advance :D
You are trying to use basename on a path which doesn't exist: $_FILES["fileToUpload"]["name"]. This is just the filename and not the path in the server.
You can just use this for unique filename:
md5($target_dir . '/' . $_FILES["fileToUpload"]["name"])
Clearly you will need to make sure that filename is always unique. If that's not an option then you could also use and this is much more likely to be unique:
md5($target_dir . '/' . $_FILES["fileToUpload"]["tmp_name"])
If you want to make sure that its always unique then this will work:
md5($target_dir . '/' . $_FILES["fileToUpload"]["tmp_name"] . time())
Several options. It just depends what you want to do with them.
Late answer but hope it helps you.
You are trying to encrypt the directory along with the file. This must be causing the error.
You should encrypt just the file and add the file extension:
$file_ext = strrchr($_FILES["fileToUpload"]["name"], '.');
$target_file = md5(basename($_FILES["fileToUpload"]["name"])).$file_ext;
And then pass it to move move_uploaded_file
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_dir.$target_file)

can i use the function md5_file to name files when upload without having conflict with names?

all the idea i need to be sure that the file doesn't saved more than one time and don't lose any file because if tow files get the same (md5) the second file will not saved
(my goal don't save the same file Twice on hard disk)
In other words,
if one user upload image and after that another user upload the same image i need to don't save the the second image because it's already exist in the hard disk all of this because
i need to save space on my hard disk
this is my code it works fine
$targetFolder = '/test/uploadify/uploads'; // Relative to the root
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;
$myhash = md5_file($_FILES['Filedata']['tmp_name']);
$temp = explode(".", $_FILES['Filedata']['name']);
$extension = end($temp);
$targetFile = rtrim($targetPath,'/') . '/' .$myhash.'.'.$extension;
if(file_exists($targetFile)){
echo 'exist';
}
// Validate the file type
$fileTypes = array('jpg','jpeg','gif','png'); // File extensions
$fileParts = pathinfo($_FILES['Filedata']['name']);
if (in_array($fileParts['extension'],$fileTypes)) {
move_uploaded_file($tempFile,$targetFile);
}
else {
echo 'Invalid file type.';
}
thanks for all of you
Well, of course you can do this, in fact this is the way I use to avoid file duplications (and I mean not having two files wit the same content and not just silly name collision).
If you are worried about collisions, then you might take a look at sha1_file:
http://es1.php.net/manual/en/function.sha1-file.php
What are the chances that two messages have the same MD5 digest and the same SHA1 digest?
I've been using the md5 approach the way you are suggesting here for image galleries and it works just fine.
Another thing to take care about is the time it takes to calculate the hash, the more complex the hash, the more time it needs, but I'm talking about processing really big batches.
If I understand your question correctly your goal is just to generate unique file names. If so, there is no point in reinventing the wheel - every hash function with fixed output length is going to have collisions - just use built in tempnam function.
Manual states:
Creates a file with a unique filename, with access permission set to 0600, in the specified directory. If the directory does not exist, tempnam() may generate a file in the system's temporary directory, and return the full path to that file, including its name.
Following should work well enough:
$targetDirectory = $_SERVER['DOCUMENT_ROOT'] . '/test/uploadify/uploads';
$uploadedFile = $_FILES['Filedata']['tmp_name'];
$targetFile = tempnam($targetDirectory, '');
move_uploaded_file($uploadedFile, $targetFile);
You could always add the systems current time in milliseconds to the filename. That plus the md5, would have a very unlikely chance of returning the same values.
It's very small, but the chance is there. You can read more here and here
I suggest you add a salt to the end of the filename to make it practically impossible for files to conflict(You should put the salt in a different md5 function though)
$salt = md5(round(microtime(true) * 1000));
$hash = md5_file($_FILES['Filedata']['tmp_name']);
$targetFile = rtrim($targetPath,'/') . '/' .$hash.$salt.'.'.$extension;
You should then insert the filename in a database so you can access it later.

How can I improve this PHP code?

I have the php code below which help me get a photo's thumbnail image path in a script
It will take a supplied value like this from a mysql DB '2/34/12/thepicture.jpg'
It will then turn it into this '2/34/12/thepicture_thumb1.jpg'
I am sure there is a better performance way of doing this and I am open to any help please
Also on a page with 50 user's this would run 50 times to get 50 different photos
// the photo has it is pulled from the DB, it has the folders and filename as 1
$photo_url = '2/34/12/thepicture_thumb1.jpg';
//build the full photo filepath
$file = $site_path. 'images/userphoto/' . $photo_url;
// make sure file name is not empty and the file exist
if ($photo_url != '' && file_exists($file)) {
//get file info
$fil_ext1 = pathinfo($file);
$fil_ext = $fil_ext1['extension'];
$fil_explode = '.' . $fil_ext;
$arr = explode($fil_explode, $photo_url);
// add "_thumb" or else "_thumb1" inbetween
// the file name and the file extension 2/45/12/photo.jpg becomes 2/45/12/photo_thumb1.jpg
$pic1 = $arr[0] . "_thumb" . $fil_explode;
//make sure the thumbnail image exist
if (file_exists("images/userphoto/" . $pic1)) {
//retunr the thumbnail image url
$img_name = $pic1;
}
}
1 thing I am curious about is how it uses pathinfo() to get the files extension, since the extension will always be 3 digits, would other methods of getting this value better performance?
Is there a performance problem with this code, or are you just optimizing prematurely? Unless the performance is bad enough to be a usability issue and the profiler tells you that this code is to blame, there are much more pressing issues with this code.
To answer the question: "How can I improve this PHP code?" Add whitespace.
Performance-wise, if you're calling built-in PHP functions the performance is excellent because you're running compiled code behind the scenes.
Of course, calling all these functions when you don't need to isn't a good idea. In your case, the pathinfo function returns the various paths you need. You call the explode function on the original name when you can build the file name like this (note, the 'filename' is only available since PHP 5.2):
$fInfo = pathinfo($file);
$thumb_name = $fInfo['dirname'] . '/' . $fInfo['filename'] . '_thumb' . $fInfo['extension'];
If you don't have PHP 5.2, then the simplest way is to ignore that function and use strrpos and substr:
// gets the position of the last dot
$lastDot = strrpos($file, '.');
// first bit gets everything before the dot,
// second gets everything from the dot onwards
$thumbName = substr($file, 0, $lastDot) . '_thumb1' . substr($file, $lastDot);
The best optimization for this code is to increase it's readability:
// make sure file name is not empty and the file exist
if ( $photo_url != '' && file_exists($file) ) {
// Get information about the file path
$path_info = pathinfo($file);
// determine the thumbnail name
// add "_thumb" or else "_thumb1" inbetween
// the file name and the file extension 2/45/12/photo.jpg
// becomes 2/45/12/photo_thumb.jpg
$pic1 = "{$path_info['dirname']}/{$path_info['basename']}_thumb.{$fil_ext}";
// if this calculated thumbnail file exists, use it in place of
// the image name
if ( file_exists( "images/userphoto/" . $pic1 ) ) {
$img_name = $pic1;
}
}
I have broken up the components of the function using line breaks, and used the information returned from pathinfo() to simplify the process of determining the thumbnail name.
Updated to incorporate feedback from #DisgruntledGoat
Why are you even concerned about the performance of this function? Assuming you call it only once (say, when the "main" filename is generated) and store the result, its runtime should be essentially zero compared to DB and filesystem access. If you're calling it on every access to re-compute the thumbnail path, well, that's wasteful but it's still not going to be significantly impacting your runtime.
Now, if you want it to look nicer and be more maintainable, that's a worthwhile goal.
The easiest way to fix this is to thumbnail all user profile pics before hand and keep it around so you don't keep resizing.
$img_name = preg_replace('/^(.*)(\..*?)$/', '\1_thumb\2', $file);
Edit: bbcode disappeared with \.

Remove spaces in file names apache

1.Hi, I have a internal use only file upload script that uploads the files to a directory. When I upload something from my computer with a spcace in the name i.e example 1.zip it uploads with a space in the name thus killing the link in a email. Is it possible to make apache remove the space when its uploaded or make it a underscore?
The second problem I am having is how would I parse this to make the link an email link with the url of the file as the body of the email amd the email addy anything?
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploaddir . $_FILES['file']['name'])) {
// uploaded file was moved and renamed succesfuly. Display a message.
echo "Link: " . "http://example.org/" . $_FILES["file"]["name"];
You just need to urlencode() your file name and everything is fine:
echo "Link: http://example.org/" . urlencode($_FILES["file"]["name"]);
But if you want to remove the spaces for another reason, you can use str_replace():
$replaced_name = str_replace(' ', '_', $_FILES["file"]["name"]);
rename($uploaddir . '/' . $_FILES['file']['name'], $uploaddir . '/' . $replaced_name);
# You should urlencode() it nonetheless:
echo "Link: http://example.org/" . urlencode($replaced_name);
Try:
$filename = $_FILES['file']['name'];
$filename = preg_replace("/[^a-zA-Z0-9]/", "", $filename);
//then
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploaddir . $filename)) {
// uploaded file was moved and renamed succesfuly. Display a message.
echo "Link: " . "http://example.org/" . $filename;
As a side note : with the code you are using, what is happening if two files with the same name are uploaded ? If you don't do a check (like "is there a file that already has that name in $uploaddir ?") the second file will replace the first one.
That might not be something you want... is it ?
If not, to solve that (potential) problem, one solution is to always rename uploaded files, with names you control. (A simple counter would probably to the trick)
Another thing is : $_FILES["file"]["name"] is sent by the client, and, as such, can probably be forged to contains whatever someone would want. If it contains something like "../../index.php" (or something like this - you get the idea), this could allow someone to put any file they want on your server.
To prevent this from happening, you shoud be sure the file name/path used as destination of move_uploaded_file does not contain anything "dangerous". A solution could be to use basename. (see, for instance, example #2 on POST method uploads)
You might also want to check the mimetype of the uploaded file, so you don't get executables, for instance -- and you should make sure files uploaded are not executable by the webserver.

Uploadify - files not showing up

I'm trying to use Uploadify (a jQuery plugin) with my CakePHP app. Locally (WampServer), it works great, but when I try it on my live server (Dreamhost), the files don't show up. I've properly chmod'ed the folders, checked the paths, etc, and I can't make any sense of why it isn't working. Here's upload.php:
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . "/app/webroot/posts/temp/";
$targetFile = str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];
$targetFile = str_replace(".", "_" . mt_rand(10000000,99999999) . ".", $targetFile);
move_uploaded_file($tempFile,$targetFile);
}
echo "1";
This script is definitely being run, but I've looked in the specified folder (and all over the filesystem), and the uploaded file(s) just aren't showing up! It's driving me crazy--hopefully someone has the answer to this. Please let me know if I should post any more code, and I will.
You could change $targetPath so it is relative to the document rather than the exact server path. I had a similar problem a while ago.
Turns out, it was this line:
$targetFile = str_replace(".", "_" . mt_rand(10000000,99999999) . ".", $targetFile);
This line was meant to append a random series of numbers to the filename to avoid collisions. However, as you can see, it's operating on the whole path, not just the filename. Well, my domain name is in my path (i.e. mydomain.com), and thus was getting changes to mydomain_12314123402.com, which obviously is a path that doesn't exist.
Man, I feel like an idiot!

Categories