I'm working on uploading a large file to my server. I have the iOS code that sets up an input and output stream. I can see that it successfully uploads to my videoUploader.php file because I have it making a response with the temporary file size and location. However, it executes the code, or so it seems before it gets the rest of the file. I cannot find any where online a full example of the server side handling.
$upload_directory = 'uploads/';
$temp_file = $_FILES['uploaded']['tmp_name'];
$filename = "testme.mp4";//basename($_FILES['uploaded']['name']);
$target_location = $upload_directory . $filename;
$size = $_FILES['uploaded']['size'];
move_uploaded_file($temp_file, $target_location);
All my files that it "moves" are 0 kb. It seems like there needs to be a way for me to tell php to wait until the temporary file is complete and then execute this code. I am an extreme novice at php, help please!
Related
I am trying to upload an image to server (I am using Google Cloud Virtual Machine) that the PHP gets from a Python script (I intend to retrieve the images from a Raspberry Pi camera sensor, but for now, I am sending a placeholder image to test the functionality of my script) that sends the image along with other parameters through a POST request. However, while the image does get uploaded, it does not get moved to a new location as it is shown in the Output I have provided below along with the code.
A question found here: php uploading a file says it is working but does not actually upload a file does have a similar problem, however the suggested solution there did not help me.
Here's the code that implements the file upload system.
PHP Upload File code:
//Upload the image
$uploadDir = "/home/username/directory/";
$uploadFile = $uploadDir . basename($_FILES["myimage"]["name"]);
if(is_uploaded_file["myimage"]["tmp_name"])
{
echo "File has been UPLOADED\n";
if(move_uploaded_file($_FILES["myimage"]["tmp_name"],$uploadFile))
{
echo "File has been MOVED";
}
else
{
echo "File has NOT been MOVED";
}
}
else
{
echo "File has NOT been UPLOADED";
}
Python code which sends a request to the PHP above:
import requests
def postData(directory):
activity = "Someone walked in"
url = 'http://35.198.114.146/index.php/sensor_readings/postdata?activity=' + activity
image = {'myimage': open(imagePath,'rb')}
r = requests.post(url,files=image)
print(r.text)
imagePath = 'cam_images/test.png'
postData(imagePath)
Output:
File has been UPLOADED
File has NOT been MOVED
I have been stuck on this problem for weeks and I am not sure on what to do. Any kind of help is appreciated. Should you need more details or code, feel free to ask me.
Thank you in advance.
Well, I've uploaded an app to Heroku, and I've discovered that I can't upload files to it. Then I started to use Dropbox as storage option, and I've done a few tests, of send and retrieve link, and all worked fine.
Now, the problem is to use the uploadFile() method on DropboxAdapter. He accepts an resource as the file, and I did'nt work well. I've done a few tests, and still no way. Here is what I am doing, if anyone could me point a solution, or a direction to this problem, please. :)
Here is my actual code for the update user (Update the user image, and get the link to the file).
$input = $_FILES['picture'];
$inputName = $input['name'];
$image = imagecreatefromstring(file_get_contents($_FILES['picture']['tmp_name']));
Storage::disk('dropbox')->putStream('/avatars/' . $inputName, $image);
// $data = Storage::disk('dropbox')->getLink('/avatars/' . $inputName);
return dd($image);
In some tests, using fopen() into a file on the disk, and doing the same process, I've noticed this:
This is when I've used fopen() on a file stored on the public folder
http://i.imgur.com/07ZiZD5.png
And this, when i've die(var_dump()) the $image that I've tried to create. (Which is a suggestion from this two links: PHP temporary file upload not valid Image resource, Dropbox uploading within script.
http://i.imgur.com/pSv6l1k.png
Any Idea?
Try a simple fopen on the uploaded file:
$image = fopen($_FILES['picture']['tmp_name'], 'r');
https://www.php.net/manual/en/function.fopen.php
You don't need an image stream but just a filestream, which fopen provides.
If this is a newby question, forgive me. I have coded a php file uploader. After hearing that hackers could attatch/disguise code to images to infect sites, I got an idea to solve that problem. To convert the upload image to another file format (png) and then to another (jpg) with 70% quality. This caused the malware to become corrupted. The problem is, this total conversion process takes a about 1 minute at top speed. The service I'm making needs to be quick to handle the file uploads so that the users can go about the work. How can I speed up this process? The upload code is below (important variables are blanked).
// upload the file
$status = "...recieving the file...";
move_uploaded_file($_FILES["file"]["tmp_name"], "$folder" . $_FILES["file"]["name"]);
$status = "...processing the file...";
// convert the file to destroy viruses
$filename21 = "$folder" . $_FILES["file"]["name"];
imagepng(imagecreatefromstring(file_get_contents($filename21)), "$folder"."debug.".$picture_newname.".png");
$imageTmp=imagecreatefrompng("$folder"."debug.".$picture_newname.".png");
imagejpeg($imageTmp, "$folder".$picture_newname.".jpg", 90);
imagedestroy($imageTmp);
These are the steps it follows:
Scan database for file with the same name
if file with same name is found, rename the current upload
receive the file
"evaluate" the file (the double conversion process to protect the server)
insert the info into the uploads database
If any other codes are needed (or if i should do some more timing) please let me know. Thanks in advance for your assistance.
This is a crazy idea. You're not just tying up the server in converting between image formats, you're also degrading the quality of every uploaded image.
I'd recommend a different approach
When a file is uploaded, use PHP's getimagesize() function to check the image. If this function returns FALSE (or an unexpected image type, or strange dimensions, etc.), then the file is corrupt and can be deleted.
Use exiftool or something similar to strip away all the metadata from the uploaded file before you store it away on the server. That way you can ensure that the file only contains image data.
Perhaps you could check that the value of $_FILES["file"]["name"] doesn't contain anything sneaky like ../../ before you use it to save the file on your server.
It's totally bad idea implement double conversion for security purpose, because of DoS attack.
Balanced solution between speed & security must contain:
Check MIME type.
Check file extension.
Check file size. (highly recommended)
Check image size. (optional, depends on application requirements)
Something like this:
$allowable_types = array(
'png' => 'image/png',
'jpeg' => 'image/jpeg',
'gif' => 'image/gif'
);
$max_file_size = 10240; // 10K limit example
$finfo = new finfo(FILEINFO_MIME_TYPE);
$type = $finfo->file($_FILES['name']['tmp_name']);
$size = filesize($_FILES['name']['tmp_name']);
$info = pathinfo($_FILES['name']['tmp_name']);
if (isset($allowable_types[$info['extension']])
and $type === $allowable_types[$info['extension']]
and $size <= $max_file_size
) {
// check image size if your app require this
move_uploaded_file($_FILES['name']['tmp_name'], $destination);
}
Update
I would not recommend to use $_FILES['file']['name'] in destination path or scan whole directory for same name. Because of some security flaws and performance drop. Better solution is to generate unique name for each image:
$new_name = uniquid() . '.' . $info['extension'];
$destination = $upload_path . $new_name;
I made a little trial using JS upon canvas and images. The final part of it calls a page where at the beginning I try to write upon the server the final image.
The process supposes that a previous file exists, not complete:
<?php
$filename = explode(".", $_POST["trans_file"]); // name of the image file
if (!unlink("transit/" . $_POST["trans_file"])) echo "File " . $_POST["trans_file"] . "not found!<br />"; // remove the partial file
$filesave = $filename[0] . ".png"; // I will save a PNG file
$filejpg = $filename[0] . ".jpg"; // but I will transform it into JPG
$data = $_POST["base64img_data"]; // here I receive the base64 image by a previous process
$data = explode(";", $data); // I remove the first part of it
$data = explode(",", $data[1]); // $data[1] now contains the base64 image complete
$image=base64_decode(chunk_split($data[1])); // $image is now a PNG file
$handle = fopen("transit/$filesave", "wb"); // Create a PNG file
fwrite($handle, $image); // write it
fclose($handle); // Close, and transform it into JPG
png2jpg("transit/$filesave", "transit/$filejpg", 100);
unlink("transit/$filesave"); // remove PNG image
I've put this at the beginning of the page, but the browser always displays the previous file, the one cancelled at the beginning, and being itself a JPG.
Strange enough (for me) this sequence is working perfectly on one server, not working on a different one!
I suppose it could be a case of asynchronous execution of PHP and JS inside the page.
How may I synchronize server and browser?
Thank you.
what happens if one process writes to the file and in the middle of the operation another process deletes it?
use .lock files so only 1 process tries to manipulate the files in question.
How can I log and get the current bytes being uploaded from a html form to a PHP script? I want to later store the current progress in a session or log so that another AJAX script can retrieve it. Here is my current code to read the current bytes but It doesn't work.
$file_type = $_FILES['Filedata']['type'];
$file_name = $_FILES['Filedata']['name'];
$file_size = $_FILES['Filedata']['size'];
$file_tmp = $_FILES['Filedata']['tmp_name'];
$filePointer = fopen($_FILES['Filedata']['tmp_name'], "rb");
$rr=0;
if ($filePointer!=false){
while (!feof($filePointer)){
$fileData = fread($filePointer, 4096);
$rr =$rr+strlen($fileData);
// Process the contents of the uploaded file here...
$_SESSION['fname']=$rr;
}
fclose($filePointer);
}
move_uploaded_file ($file_tmp, "files/".$file_name);
You can not access the uploaded bytes that way as the script doesnt get called till the file is already uploaded.
Your server needs to have APC, or similar pecl packages installed
http://devzone.zend.com/1812/using-apc-with-php/
Or by using the HTML5 file api
http://www.matlus.com/html5-file-upload-with-progress/
The HTML5 is better as you dont have to change anything on the php side just setup the scripts to receive the files, but would require that the user's browser support the HTML5 file api.
There is a PECL package: http://pecl.php.net/package/uploadprogress
Else check this:
http://devpro.it/upload_progress/
http://www.johnboy.com/php-upload-progress-bar/
You have to find the correct file in tmp folder and measure the size. This size must be shown on a page which is crawled via AJAX every some seconds. The problem is how to match the correct session and file. But it is not impossible...