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!
Related
I'd like to learn how to build my own basic script to upload/resize and rename an image.
Right now I'm using dropzone.js for the client-side code, but I'm struggling for the server-side.
Here is what my upload.php script looks like right now (from a dropzone tutorial):
<?php
$ds = DIRECTORY_SEPARATOR;
$storeFolder = 'user/avatar';
if (!empty($_FILES)) {
$tempFile = $_FILES['file']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $ds. $storeFolder . $ds;
$targetFile = $targetPath. $_FILES['file']['name'];
move_uploaded_file($tempFile,$targetFile);
}
?>
It's working fine, the image gets uploaded where I want, exept I don't understand how it works, and that may be problem for the next steps of my script.
What is $_FILES['file']['tmp_name'] exactly ? Why is it not directly $_FILES['file']['name'] ?
How does move_uploaded_file($tempFile,$targetFile); ? Why does it need $tempFile ?
What's the difference between $_FILES['file'] and $_FILES['image'] ?
Last question, what is the best approach now to set-up a basic resizing function ? My goal is to resize the image to 150*150px no matter its original size.
Hopefully I can get some help to figure out all this,
Thanks !
From what I understand, this is a Linux security thing. Linux uploads the file to a temporary folder, and only after it's done can it move the file from where it's uploaded to where you're wanting it to go. That's why you have to do the multiple steps.
As for resizing an image, I don't think you can do this directly. I think you have to use imagecopyresized().
http://php.net/manual/en/function.imagecopyresized.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.
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.
What is this code doing?
<?php
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
$targetFile = str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];
move_uploaded_file($tempFile,$targetFile);
echo str_replace($_SERVER['DOCUMENT_ROOT'],'',$targetFile);
}
?>
It is basically uploading a file and echoing the target file's name.
There should also be something like an HTML form to send the file to this script.
It accepts an user uploaded file, and puts it in your webroot in a folder, specified by the user. Then it outputs the path of the uploaded file.
This code is to upload a file in the destination directory. Is there anything else do you want to understand.
This will upload the file in the path you have in variable $_REQUEST['folder']
Storing files uploaded (possibly via HTML form) onto server.
It's accepting a file posted by a HTML form and uploading it to a certain directory within a server. After that it's displaying the location of the file on screen (in the browser).
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.