FTP image upload doesn't work properly in PHP - php

I have a web application which is connected to a website. my web application runs in a Ubuntu server(LAMP). in my web application, there is a function called add a new client. when adding a new client user have to set an image for the client. when a user clicks the save button, the image should upload to the Linux server itself and I'm sending the image to my shared hosting server where the website is hosted using FTP. This perfectly works in my windows localhost (I'm using wamp server). but when I put my web application to the Ubuntu server, FTP image upload works sometimes and sometimes it doesn't work.
this is my code
private $config_ftp = array('hostname'=>'xxxx.com','username'=>'xxx#xxxxx.com','password'=>'xxxxx','passive'=>FALSE,'debug'=>FALSE,'port'=>21);
$source_original = $this->img_path['img_original'] . $file_name;
$destination_original = $this->full_file_path['img_original'] . $file_name;
if($this->ftp->upload($source_original,"./assets".$destination_original)) {
$this->response['msg']="Images Uploaded successfully!";
$this->response['status']=true;
}
when I check the destination folder after the upload it looks like this. The file size is 0kb. sometimes it gets uploaded properly. and I have to mention again this process works completely fine in windows localhost.
Thanks.

$this->ftp->upload() code is need to be shown to find actual problem.
in that if $image_size = $_FILES['image']['size']; $image_size is 0 that you have problem in image otherwise you can successfully upload it by move_uploaded_file($_FILES['image']['tmp_name'], "YOUR-UPLOAD-FOLDER/YOUR-IMAGE-NAME-PLUS-EXTENSION"); .
similar problem : 0 kb when upload and store image to server

The issue was there in my ftp_config.
what i had to do is set passive and debug as true
private $config_ftp = array('hostname'=>'xxxx.com','username'=>'xxx#xxxxx.com','password'=>'xxxxx','passive'=>TRUE,'debug'=>TRUE ,'port'=>21);

Related

Replace image on server and show previous image until the new one is fully uploaded

I'm uploading to a lightspeed server through "ncftpput" an image taken from a raspberry camera every minute.
I want to be able to show the updated image and I know how I can force the browser to use the latest version instead of the cached image.
So, everything works properly except that, if I refresh the image (like through shift-F5) during image upload, the browser reports image contains errors (or shows image partially).
Is there any way to ensure the image is fully loaded before serving the new one?
I'm not sure if I should operate on ncftp or use PHP to ensure the swap happens only after complete loading.
Image is a progressive jpg but that doesn't help...
Any suggestion?
Thanks
I ended up with NOT using FTP because, as Viney mentioned, the webserver doesn't know if the upload is completed.
I'm using "curl" which has the advantage of being preinstalled on raspberry distro and a php upload page.
It seems that PHP will pass the new image only once fully uploaded and avoid creating the issue when image is still partially uploaded.
So, to recap:
raspberry (webcam), after having taken the image:
curl -F"somepostparam=abcd" -F"operation=upload" -F"file=#filename.jpg" https://www.myserver.com/upload.php
PHP server code:
$uploadfile = '/home/domain/myserver.com/' . basename($_FILES['file']['name']);
move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile);
$content = file_get_contents($uploadfile);
Problem is this: you open browser (at 07:00:10 AM) image.jpg gets rendered now say it's 07:01:00 you hit refresh in browser but the raspberry is already started uploading image.jpg say it would take 3 secs to complete the full upload but the server doesn't know about ftp and would read whatever bytes are there in image,jpg and flushes to your browser. Had it been a baseline JPG it would have shown a cropped(in height) image but since it's a progressive JPG it would be messed up.I am not aware of whether it's possible but try looking up if you FTP supports a locking file.
How to solve ?
The best way is to let you server know that the file it's accessing is in a write process.If your ftp supports advisory locks then you can use it so when server tries accessing you file ( via system call) kernel would instruct it that the file is currently locked so the server will wait until ftp releases that lock.
In vsftp there would be a option lock_upload_files in VSFTPD.CONF setting yest would enable this feature
If you are unable to work out above solution then you can use some trick like checking file last modified time if it's almost same as current time then you make php wait for some guessed time that you think is avg. upload time of your file.For this method you should use PHP to send it to browser instead of server. ie Just change the src of your image from '/path/to/image.jpg' to 'gen-image.php'. This script will read that image and would flush it to the browser
gen-image.php
$guessedUploadTime = 3;// guessed time that ncftpput takes to finish
$currTime = time();
$modTime = filemtime('image.jpg');
if( ($currTime - $modTime) < $guessedUploadTime)
{
sleep($guessedUploadTime);
}
$file = '/path/to/image.jpg';
$type = 'image/jpeg';
header('Content-Type:'.$type);
readfile($file);
Note that the above solution is not ideal because if file has been just done uploading it won't be modified for another 57 seconds yet the browser request say at 07:02:04 has to wait unnecessarily for 3 seconds because mtime would be 07:02:03 and browser would get file only after 07:02:06. I would recommend you to search for some way(proly cmd based) to make server and ftp go hand in hand one should know the status of the other because that is the root cause of this problem.

FTP corrupts files after certain delay and/or size

i am building a few Excel files with PHPExcel and store them on the server running the script.
This part works well.
i then try to send them to my client's ftp server using ftp_put, but the files arrive corrupted to the server.
When opening them after downloading them back from the ftp server with Filezilla, i get an error saying that there is a problem with the content of the file and that they can try to repair it as much as they can if i wish so. Doing so doesn't help.
if the excel file is under 100-120k its sent uncorrupted, bigger than that it gets corrupted.
script to send via ftp
$conn_id = ftp_connect($hostFTP);
if($login_result = ftp_login($conn_id, $userFTP, $passwordFTP))
{
ftp_pasv($conn_id, true);
if(ftp_put($conn_id, $remote_path.$output_filename, $localPath.$output_filename, FTP_BINARY))
{
$log = new Logs("listes.log", "Uploaded $output_filename");
}
else
{
$log = new Logs("listes.log", "FAIL Uploading $output_filename");
}
ftp_close($conn_id);
}
Am i doing something wrong? what can i do?
edit :
comparing the files in text show some differences starting at line 231, which i assume is around the 100-120k mark
tried with an image(jpg) and it also gets corrupted (top of image is fine, but at a point it just corrupts and the rest of the image is pretty much single colored), so problem isnt with excel;
Is it possible that the server (opensuse) limits ftp? and if so how?
Well i've found the problem, its not the code. its the internet service. We changed the internet provider yesterday and the ftp now works fine. I guess the ftp connection was being interrupted with the previous provider.

How to upload file in php from browser with no user input

I am working on a php web app .
I need to upload a file to the web server, with customer info - customers.csv.
but this process needs to be automated ,
The file will be generated in a Point of Sale app , and the app can open a browser window with the url ...
first i taught i would do something like this www.a.com/upload/&file=customers.csv
but read on here that is not possible,
then i taught i would set a value for the file upload field and submit form automatically after x seconds. Discovered thats not possible .
Anybody with a solution , will be appreciated .
EDIT
I have tried this and it works ,file is uploaded to remote server
is it working only because the php script is running on the same pc where csv is sitting ???
$file = 'c:\downloads\customers.csv';
$remote_file = 'customers.csv';
// set up basic connection
$conn_id = ftp_connect('host.com');
// login with username and password
$login_result = ftp_login($conn_id,'user','password');
// upload a file
if (ftp_put($conn_id, $remote_file, $file, FTP_ASCII)) {
echo "successfully uploaded $file\n";
} else {
echo "There was a problem while uploading $file\n";
}
// close the connection
ftp_close($conn_id);
This is of course not possible, imagine how this could be abused to upload on linux as example the /etc/passwd. The only way it might be possible is to use a Java Applet, but this is for sure not the best way.
You could try to let your PoS Application make a web request with the customers.csv file and let a WebAPI handle the upload, this may be possible, but I have no expierence with Point of Sale Applications.
Best might be, if the solution above cannot be considered, to just prompt the user to provide the file above and check over name + content if it is the correct one.
This is a bit tricky, but if your CSV is not too long, you could encode it in base64, send to the webserver as a GET parameter and then, in the server side, decode and store it as a CSV file.
If the file is too big to do that, you have to use other method, like the java applet pointed by #D.Schalla or even install and configure a FTP server, and make the Point of Sale app uploads the file there.
Other alternative, specially good if you cannot modify the sale app, is to install a web server in the client side and write a small php script to handle the upload process. In this way, the sale app could call a local url (something like: http:// localhost/upload.php) and it's this script the one in charge to upload the file which can be achieve with a classical HTTP POST, a FTP connection or any other way you can think about.
MY Solution , which will work with out setting up web server on client side.
This is for windows but can be adapted to linux
On client side
Local Application opens cmd and runs this command ftp -n -s:C:\test.scr
WHICH opens test.scr - a file with ftp commands e.g.
open host.com
user1
passwOrd
put C:\downloads\customers.csv public_html/customers.csv
more info here :
http://support.microsoft.com/kb/96269
more commands :
http://www.nsftools.com/tips/MSFTP.htm#put

Uploading a local file to remote server with PHP and FTP

I've been trying to make a system that can upload large files, originally i used HTTP but this had a number of problems with settings that needed to be changed. So i thought i'd give it a go with FTP.
Now i have a ftp connection in PHP and it works find, i can view folders and files as well as make directories, what i can't seem to figure out though is how to get hold of a local file and upload it.
I have been reading lots of information and tutorials such as the PHP manual and a tutorial i found on nettuts But i'm struggling to do it. The tutorial says you can upload a local file but i must be missing something.
Here is the upload method i'm using:
public function uploadFile ($fileFrom, $fileTo)
{
// *** Set the transfer mode
$asciiArray = array('txt', 'csv');
$extension = end(explode('.', $fileFrom));
if (in_array($extension, $asciiArray))
$mode = FTP_ASCII;
else
$mode = FTP_BINARY;
// *** Upload the file
$upload = ftp_put($this->connectionId, $fileTo, $fileFrom, $mode);
// *** Check upload status
if (!$upload) {
$this->logMessage('FTP upload has failed!');
return false;
} else {
$this->logMessage('Uploaded "' . $fileFrom . '" as "' . $fileTo);
return true;
}
}
When trying to upload a file i use this:
$fileFrom = 'c:\test_pic.jpg';
$fileTo = $dir . '/test_pic.jpg';
$ftpObj -> uploadFile($fileFrom, $fileTo);
I thought this would get the file from my machine that is stored in the c: and upload it to the destination but it fails (Don't know why). So i changed it a little, changed the $fileFrom = test_pic.jpg and up the picture in the same folder on the remote server. When i ran this code the script copied the file from the one location to the other.
So how would i go about getting the file from my local machine to be sent up to the server?
Thanks in advance.
Using this you would upload a file from your PHP server to your FTP server, what actually not seems to be your target.
Create an upload form which submits to this PHP file. Store this file temporarily on your server and then upload it to your FTP server from there.
If your try would actually work, this would be a major security issue, because a PHP file would have access to any files on my local machine.

File upload with breaks

I'd like to upload large files to my server, but i would like to be able to make breaks (for example, the user must be able to shut down his computer and to continue after reboot) in the upload process.
I think i can handle the client side upload, but I don't know how to make the server side. What is the best way to make it on the server side? Is PHP able to do that ? Is PHP the most efficient?
Thanks a lot
If you manage to do the client side do post the file in chunks, you could do something like this on the server side:
// set the path of the file you upload
$path = $_GET['path'];
// set the `append` parameter to 1 if you want to append to an existing file, if you are uploading a new chunk of data
$append = intval($_GET['append']);
// convert the path you sent via post to a physical filename on the server
$filename = $this->convertToPhysicalPath($path);
// get the temporary file
$tmp_file = $_FILES['file']['tmp_name'];
// if this is not appending
if ($append == 0) {
// just copy the uploaded file
copy($tmp_file, $filename);
} else {
// append file contents
$write_handle = fopen($filename, "ab");
$read_handle = fopen($tmp_file, "rb");
$contents = fread($read_handle, filesize($tmp_file));
fwrite($write_handle, $contents);
fclose($write_handle);
fclose($read_handle);
}
If you are trying to design a web interface to allow anyone to upload a large file and resume the upload part way though I don't know how to help you. But if all you want to do is get files from you computer to a server in a resume-able fashion you may be able to use a tool like rsync. Rsync compare the files on the source and destination, and then only copies the differences between the two. This way if you have 50 GB of files that you upload to your server and then change one, rsync will very quickly check that all the other files are the same, and then only send your one changed file. This also means that if a transfer is interrupted part way through rsync will pick up where it left off.
Traditionally rsync is run from the command line (terminal) and it is installed by default on most Linux and Mac OS X.
rsync -avz /home/user/data sever:src/data
This would transfer all files from /home/user/data to the src/data on the server. If you then change any file in /home/user/data you can run the command again to resync it.
If you use windows the easiest solution is probably use DeltaCopy which is a GUI around rsync.download

Categories