php upload image with ftp problem - php

I am using the code below to upload an image through ftp
$sFile=$ftp_dir."/".$image_name;
$image=$database_row["image"];//image is store in database
$fh = tmpfile();
$fwrite($fh, $image);
$uploadFile = ftp_fput($conn_id, $sFile, $fh, FTP_ASCII);
fclose($fh);
The ftp is creating the file and has a size BUT the file i get is not an image.When try to open on image viewer i get error.
Before switch to ftp i had this code
$image=$database_row["image"];//image is store in database
$file = fopen( "images/".$image_name, "w" );
fwrite( $file, $image);
fclose( $file );
and was working fine, but now i have to use ftp.
What am i missing.

You need to fseek to the beginning of the file after writing content to it and you need to use binary upload mode:
$sFile=$ftp_dir."/".$image_name;
$image=$database_row["image"];//image is store in database
$fwrite($fh, $image);
fseek($fh, 0);
$uploadFile = ftp_fput($conn_id, $sFile, $fh, FTP_BINARY);
fclose($fh);

Try using FTP_BINARY instead of FTP_ASCII. If all else fails, open the resulting file with a hex editor.

you are telling ftp to read the image as ascii (text)
change it ot FTP_BINARY.

//turn passive mode on then it will work fine
ftp_pasv($conn_id, true);

Related

how to pass file name to ftp_put function?

It's a simple code to resize an image and send it to ftp server:
$info = getimagesize($_FILES["personalPhoto"]["tmp_name"]);
$image = imagecreatefromjpeg($_FILES["personalPhoto"]["tmp_name"]);
ob_start();
imagejpeg($image,null, 1);
$resizedImage = ob_get_contents();
ob_end_clean();
ftp_put($ftpConn,'/Kamil/HostMe/AllImages/'.$fileName.'.jpg',$_FILES["personalPhoto"]["tmp_name"],FTP_BINARY);
ftp_put($ftpConn,'/Kamil/HostMe/AllImages/'.$fileName.'.jpg',$resizedImage,FTP_BINARY);
The first ftp_put command works fine (sends the original image to server)
the second ftp_put command which is supposed to send the resized image is not working. any ideas?
$resizedImage is a PHP variable, not a physical file. To solve your problem, you can write $resizedImage into a file then set this to ftp_put. Such as:
$file = "/tmp/somefile.jpg";
file_put_contents($file, $resizedImage);
ftp_put(
$ftpConn,
'/Kamil/HostMe/AllImages/'.$fileName.'.jpg',
$file,
FTP_BINARY
);

unlink base64 encoded image not working

hi guys ive created a base64 encoded image captured with web cam now i convert the .png to .jpg all works fine but now i get two images on server both .png and .jpg how do i go about deleting the .png or is their a way to convert to jpg without saving .png image to disk thanx here my code
$rawData = $_POST['imgBase64'];
$filteredData = explode(',', $rawData);
$unencoded = base64_decode($filteredData[1]);
$randomName = rand(1000, 99999999999);
//Create the image
$fp = fopen('user/'.$randomName.'.png', 'w');
fwrite($fp, $unencoded);
//convert image from png to jpg
$image = imagecreatefrompng('user/'.$randomName.'.png');
imagejpeg($image, 'user/'.$randomName.'.jpg', 80);
unlink($fp);
ive tried it with
unlink($image);
unlink($_SERVER['DOCUMENT_ROOT'] . "/user/.$randomName.'.png'");
imagedestroy($fp);
imagedestroy($image);
Use the function unlink() but passing the file name to it instead of the file handler.
So from your example it would be:
EDIT: You might need to close the file first:
fclose( $fp );
unlink( 'user/'.$randomName.'.png' );
as far as i understand all you need is:
$data = base64_decode( $_POST['imgBase64']);
// image resource from your string
$image = imagecreatefromstring($data);
imagejpeg($image, 'user/'.$randomName.'.jpg', 80);

Why would uploading a zip file via ftp_fput return true but not upload the file?

The following command returns true and uploads the text XML file to the FTP server:
if (ftp_put($this->ftpConnectionId, $this->remoteXmlFileName, $this->localXmlFileName, FTP_ASCII)) {
However, when I try to upload a .zip file intead of a text XML file, it still returns true but does not upload the file:
if (ftp_put($this->ftpConnectionId, $this->remoteXmlFileName, $this->localXmlFileName, FTP_BINARY)) {
I found that if I simply rename the zip file to ".xml", it WILL upload the file but the .zip file is corrupted.
But if I rename the zip file to ".zip.xml" it again returns true but does not upload the file.
What could be the reasons for this odd behavior?
Additional Info:
A zip file can be uploaded via FileZilla no problem with the same account.
I also am specifing:
ftp_pasv($this->ftpConnectionId, true);
A zipfile is a binary file. That's probably why uploading it as .xml corrupts the file. Try specifying FTP_BINARY instead of FTP_ASCII. FTP_BINARY will work for ascii files too, but not vice versa, so you can better always use FTP_BINARY than always FTP_ASCII.
The ftp server may reject the file for many reasons, so it may allow the upload at first, but then not save the file. The ascii/binary problem may be one, but also some file extensions may be blacklisted, or the file could be too big. The latter is unlikely, though, since uploading the zipfile with a different extensions worked for you.
I think the ftp server actively ignores zip files.
This is because zip file contains Files and may be is size is greater than your XMl
We have used this code to upload entire directory over ftp
Try this code. This will work for your ftp
//Start ftp upload code
$ftp_user_name =$_SESSION['upload']['username'];
$ftp_user_pass = $_SESSION['upload']['password'];
$ftp_server = $_SESSION['upload']['host'];
$sourcepath = $_SESSION['upload']['source'];
$dest_folder = $_SESSION['upload']['dest_folder'];
$conn_id = #ftp_connect($ftp_server,21) or die("Couldn't connect to $ftp_server");
if (#ftp_login($conn_id, $ftp_user_name, $ftp_user_pass)) {
ftp_set_option($conn_id, FTP_TIMEOUT_SEC, 70000000000000000); // Set the network timeout to 10 seconds
ftp_copyAll($conn_id, $sourcepath, $dest_folder);
}
function ftp_copyAll($conn_id, $src_dir, $dst_dir) {
if(is_dir($dst_dir)){
return "Dir $dst_dir Already exists";
} else {
$d = dir($src_dir);
ftp_mkdir($conn_id, $dst_dir); //echo "creat dir $dst_dir";
while($file = $d->read()) { // do this for each file in the directory
if ($file != "." && $file != "..") { // to prevent an infinite loop
if (is_dir($src_dir."/".$file)) { // do the following if it is a directory
$src_dir_path=$src_dir."/".$file;
$dst_dir_path=$dst_dir."/".$file;
ftp_copyAll($conn_id, $src_dir_path, $dst_dir_path); // recursive part
} else {
$upload = ftp_put($conn_id, $dst_dir."/".$file, $src_dir."/".$file, FTP_BINARY); // put the files
//echo "creat files::: ".$dst_dir."/".$file ."";
echo " ";
}
}
ob_flush() ;
flush();
usleep(90000);
//sleep(1);
}
$d->close();
}
return true;
}

getimagesize() on stream instead of string

I'm using Valum's file uploader to upload images with AJAX. This script submits the file to my server in a way that I don't fully understand, so it's probably best to explain by showing my server-side code:
$pathToFile = $path . $filename;
//Here I get a file not found error, because the file is not yet at this address
getimagesize($pathToFile);
$input = fopen('php://input', 'r');
$temp = tmpfile();
$realSize = stream_copy_to_stream($input, $temp);
//Here I get a string expected, resource given error
getimagesize($input);
fclose($input);
$target = fopen($pathToFile, 'w');
fseek($temp, 0, SEEK_SET);
//Here I get a file not found error, because the image is not at the $target yet
getimagesize($pathToFile);
stream_copy_to_stream($temp, $target);
fclose($target);
//Here it works, because the image is at the desired location so I'm able to access it with $pathToFile. However, the (potentially) malicious file is already in my server.
getimagesize($pathToFile);
The problem is that I want to perform some file validation here, using getimagesize(). getimagesize only supports a string, and I only have resources available, which result in the error: getimagesize expects a string, resource given.
It does work when I perform getimagesize($pathTofile) at the end of the script, but then the image is already uploaded and the damage could already have been done. Doing this and performing the check afterwards and then maybe deleting te file seems like bad practice to me.
The only thing thats in $_REQUEST is the filename, which i use for the var $pathToFile. $_FILES is empty.
How can I perform file validation on streams?
EDIT:
the solution is to first place the file in a temporary directory, and perform the validation on the temporary file before copying it to the destination directory.
// Store the file in tmp dir, to validate it before storing it in destination dir
$input = fopen('php://input', 'r');
$tmpPath = tempnam(sys_get_temp_dir(), 'upl'); // upl is 3-letter prefix for upload
$tmpStream = fopen($tmpPath, 'w'); // For writing it to tmp dir
stream_copy_to_stream($input, $tmpStream);
fclose($input);
fclose($tmpStream);
// Store the file in destination dir, after validation
$pathToFile = $path . $filename;
$destination = fopen($pathToFile, 'w');
$tmpStream = fopen($tmpPath, 'r'); // For reading it from tmp dir
stream_copy_to_stream($tmpStream, $destination);
fclose($destination);
fclose($tmpStream);
PHP 5.4 now supports getimagesizefromstring
See the docs:
http://php.net/manual/pt_BR/function.getimagesizefromstring.php
You could try:
$input = fopen('php://input', 'r');
$string = stream_get_contents($input);
fclose($input);
getimagesizefromstring($string);
Instead of using tmpfile() you could make use of tempnam() and sys_get_temp_dir() to create a temporary path.
Then use fopen() to get a handle to it, copy over the stream.
Then you've got a string and a handle for the operations you need to do.
//Copy PHP's input stream data into a temporary file
$inputStream = fopen('php://input', 'r');
$tempDir = sys_get_temp_dir();
$tempExtension = '.upload';
$tempFile = tempnam($tempDir, $tempExtension);
$tempStream = fopen($tempFile, "w");
$realSize = stream_copy_to_stream($inputStream, $tempStream);
fclose($tempStream);
getimagesize($tempFile);

Image Remote Upload Script

I'm having trouble to make a php file that'll be able to copy remote images and save it to a directory.
so i'm going to input a set of image urls into the first text box, and when run the image will grab those images and save them to a specified directory and display the new set of urls. :)
How can i do that?
Place this code in your script.php
<?php
$image = 'http://remote.com/image.jpeg';
file_put_contents(dirname(__FILE__).'/'.basename($image), file_get_contents('http://remote.com/image.jpeg'));
This should start you off
header("Content-Type: image/jpeg");
echo file_get_contents("http://www.somewebsite.com/images/image.jpg");
You could then save this file to a local directory
I'd start by using file_get_contents() along with the fopen(), fwrite(), and fclose() gang.
<?php
foreach( $_POST['image'] as $image ) {
$f = fopen( "/path/to/image/folder/".basename( $image ) ); //Open image file
fwrite( $f, file_get_contents( $image ) ); //Write the contents of the web image to the newly created image on your server
fclose( $f ); //Close the file
}
?>

Categories