CURL uploads blank file by FTP - php

I am using this curl script to try to upload user selected files by FTP. It uploads the files to the server but they are all blank. Why is this happening?
if (!empty($_FILES['userfile']['name'])) {
$ch = curl_init();
$localfile = $_FILES['upload']['tmp_name'];
$fp = fopen($localfile, 'r');
curl_setopt($ch, CURLOPT_URL, 'ftp-addy-here'.$_FILES['userfile']['name']);
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localfile));
curl_exec ($ch);
$error_no = curl_errno($ch);
curl_close ($ch);
if ($error_no == 0) {
$error = 'File uploaded succesfully.';
} else {
$error = 'File upload error.';
}
} else {
$error = 'Please select a file.';
}
echo $error;

Line 3, right now it says:
$localfile = $_FILES['upload']['tmp_name'];
Change it to:
$localfile = $_FILES['userfile']['tmp_name'];

You didn't check if the initial file upload succeeded. Checking for the presence of the remote filename is NOT an indication that it got uploaded. The 100% reliable method to ensure the upload worked is
if ($_FILES['userfile']['error'] === UPLOAD_ERR_OK) {
... ftp stuff ...
} else {
die("Upload failed with error code: {$_FILES['userfile']['error']}");
}
The codes/constants are documented here: http://php.net/manual/en/features.file-upload.errors.php

Related

How to get correctly a file via file_get_content or curl

I tried to download a file via Icecat. The file need an access to be downloaded.
My problem is :
the file_get_content does'nt download the file. My directory is on 777 and the path is correct.
if I insert the document inside the directory, the file is not unzipped.
public function getIceCatFile() {
set_time_limit (0);
$url = 'https://data.Icecat.biz/export/freexml/EN/daily.index.xml.gz';
$context = stream_context_create(array('http' => array( 'header' => "Authorization: Basic " . base64_encode($this->username . ":" . $this->password) )));
if ($this->checkDirectoryIceCat() === true) {
// does'nt download the file inside the server directory
file_get_contents($url, true, $context);
$file = $this->IceCatDirectory . 'daily.index.xml.gz';
if (is_file($file)) {
$zip = new \ZipArchive;
// error failed same if I include the file inside the directory
$icecat_file = $zip->open($this->IceCatDirectory . 'files.index.xml.gz');
if ($icecat_file === true) {
$zip->extractTo($icecat_file);
$zip->close();
echo 'file downloaded and unzipped';
} else {
echo 'failed';
}
} else {
echo 'error no file found in ' . $file;
}
}
}
Make a try like this to download file that has username and password authentication using PHP Curl,
$localfile = fopen($file_store_locally, 'wb'); // open with write enable
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FILE, $localfile);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, "username:password"); // see here for auth
curl_exec($ch);
curl_close($ch);
fclose($localfile); //store file data to local file

downloading zip file from curl results in cpgz file after unzipping

I am trying to write some php (new to php) that downloads a zip file from a remote server using curl and unzips it to a wordpress theme directory. The unzipping through php is failing reporting a result of 19 which from what I've found indicates no zip file. However when I check the directory, the zip file is there. If I unzip it I end up with a zip.cpgz file. I'm not sure if this is a problem with my code or if it's a way the server is sending the file. Here's my code. Thanks.
$dirpath = dirname(__FILE__);
$themepath = substr($dirpath, 0, strrpos($dirpath, 'wp-content') + 10)."/themes/";
//make call to api to get site information
$pagedata = file_get_contents("https://ourwebsite/downloadzip.php?industryid=$industry");
$jsondata = json_decode($pagedata);
$fileToWrite = $themepath.basename($jsondata->zip_file_url);
$zipfile = curl_init();
curl_setopt($zipfile, CURLOPT_URL, $jsondata->zip_file_url);
curl_setopt($zipfile, CURLOPT_HEADER, 1);
curl_setopt($zipfile, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($zipfile, CURLOPT_BINARYTRANSFER, 1);
$file = curl_exec($zipfile);
if ($file == FALSE){
echo "FAILED";
}else{
$fileData = fopen($fileToWrite,"wb");
fputs($fileData,$file);
}
curl_close($zipfile);
if (file_exists($fileToWrite)){
$zip = new ZipArchive;
$res = $zip->open($fileToWrite);
if ($res === TRUE)
{
$zip->extractTo($themepath);
$zip->close();
echo 'Theme file has been extracted.';
}
else
{
echo 'There was a problem opening the theme zip file: '.$res;
}
}
else{
echo("There was an error downloading, writing or accessing the theme file.");
}
This should do it:
<?php
set_time_limit(0);
$industry = "industryid"; //replace this
$url = "https://ourwebsite/downloadzip.php?industryid=$industry";
$tmppath = "/tmp/tmpfile.zip";
$themdir = "/your/path/wp-content/themes/";
$fp = fopen ($tmppath, 'w+');//This is the file where we save the zip file
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FILE, $fp); // write curl response to file
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch); // get curl response
curl_close($ch);
fclose($fp);
if (file_exists($tmppath)){
$zip = new ZipArchive;
$res = $zip->open($tmppath);
if ($res === TRUE)
{
$zip->extractTo($themdir);
$zip->close();
echo 'Theme file has been extracted.';
}
else
{
echo 'There was a problem opening the theme zip file: '.$res;
}
}
else{
echo("There was an error downloading, writing or accessing the theme file.");
}
?>

Resume an ftp upload with curl

i'm buidling a php script to upload larges files from a local php server to a distant ftp server with log of progress in a mysql base. Evrything work fine, but i get problem with the resume function and i can't find any clear information of the process to follow to resume an ftp upload with curl. my code bellow :
$fp = fopen($localfile, 'r');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_NOPROGRESS, false);
curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, 'curlProgressCallback'); // lof progress to base
curl_setopt($curl, CURLOPT_READFUNCTION, 'curlAbortCallback'); // check if user request abort
curl_setopt($curl, CURLOPT_URL, $ftp);
curl_setopt($curl, CURLOPT_PORT, FTPPort);
curl_setopt($curl, CURLOPT_LOW_SPEED_LIMIT, 1000);
curl_setopt($curl, CURLOPT_LOW_SPEED_TIME, 20);
curl_setopt($curl, CURLOPT_USERPWD, FTPLog . ":" . FTPPass);
curl_setopt($curl, CURLOPT_FTP_CREATE_MISSING_DIRS, true);
curl_setopt($curl, CURLOPT_UPLOAD, 1);
if($resume){
$startFrom=ftpFileSize($dest); // return the actual file size on the ftp server
}else{
$startFrom=false;
}
if($startFrom){
curl_setopt ($curl, CURLOPT_FTPAPPEND, 1);
curl_setopt($curl, CURLOPT_RESUME_FROM, $startFrom);
fseek($fp, $startFrom, SEEK_SET);
$sizeToUp=filesize($localfile);//-$startFrom;
}else{
$sizeToUp=filesize($localfile);
}
curl_setopt($curl, CURLOPT_INFILE, $fp);
curl_setopt($curl, CURLOPT_INFILESIZE, $sizeToUp);
curl_exec($curl);
If someone call help me on this or redirect me on a valid example it will be very helfull and appreciate.
Tks for your feedback
Mr
I do not think cURL & PHP can do this.
Are you using Linux? If so look at aria2. It supports resumable connections and supports FTP. I am not sure if it will do exactly what you want.
So i've abort my research to make resume with curl, not enought help or documentation on it,
And it's really more easy to do it with ftp_nb_put. So i f its can help someone, you can find a exemple of my final code bellow :
define("FTPAdd","your serveur ftp address");
define("FTPPort",21);
define("FTPTimeout",120);
define("FTPLog","your login");
define("FTPPass","your password");
function ftpUp_checkForAndMakeDirs($ftpThread, $file) {
$parts = explode("/", dirname($file));
foreach ($parts as $curDir) {
if (#ftp_chdir($ftpThread, $curDir) === false) { // Attempt to change directory, suppress errors
ftp_mkdir($ftpThread, $curDir); //directory doesn't exist - so make it
ftp_chdir($ftpThread, $curDir); //go into the new directory
}
}
}
function ftpUp_progressCallBack($uploadedData){
global $abortRequested;
//you can do any action you want while file upload progress, personaly, il log progress in to data base
//and i request DB to know if user request a file transfert abort and set the var $abortRequested to true or false
}
function ftpUp($src,$file,$dest,$resume){
global $abortRequested;
$conn_id = ftp_connect(FTPAdd,FTPPort,FTPTimeout);
if ($conn_id==false){
echo "FTP Connection problem";return false;
}else{
$login_res = ftp_login($conn_id, FTPLog, FTPPass);
if ($login_res){
$ftpThread=$conn_id;
}else{
echo "FTP Authentification error";return false;
}
}
$fp = fopen($src, 'r');
ftpUp_checkForAndMakeDirs($ftpThread, $dest); //verif et creation de l'arborescence sur le serveur ftp
ftp_set_option ($ftpThread, FTP_AUTOSEEK, TRUE); // indispensable pour pouvoir faire du resume
if($resume){
$upload = ftp_nb_fput ($ftpThread, $file, $fp ,FTPUpMode, FTP_AUTORESUME);
}else{
$upload = ftp_nb_fput ($ftpThread, $file, $fp ,FTPUpMode);
}
///////////////////////////////////////////////////////////////////////////////////
//uploading process
while ($upload == FTP_MOREDATA) {
//progress of upload
ftpUp_progressCallBack(ftell ($fp));
//continue or abort
if(!$abortRequested){
$upload = ftp_nb_continue($ftpThread);
}else{
$upload = "userAbort";
}
}
///////////////////////////////////////////////////////////////////////////////////
//end and result
ftpUp_progressCallBack(ftell ($fp));
if ($upload != FTP_FINISHED) {
#fclose($fp);
#ftp_close ($ftpThread);
if ($abortRequested){
echo "FTP Abort by user : resume needed";
}else{
echo "FTP upload error : ".$upload." (try resume)";
}
}else{
#fclose($fp);
#ftp_close ($ftpThread);
echo "upload sucess";
}
}
$file="test.zip";
$src = "FilesToUp/" . $file;
$destDir = "www/data/upFiles/";
$dest = $destDir . $file;
$abortRequested=false;
ftpUp($src,$file,$dest,true);
I was searching for a viable answer using CURL + PHP to resume a transfer that was broken and could not find clear, viable solution on the internet. This is an OLD question but I figured it did need a proper answer. This is the result of a day or two of research. See functions below and quick usage example.
Connect function:
function ftp_getconnect($uName, $pWord, $uHost)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, "$uName:$pWord");
curl_setopt($ch, CURLOPT_URL, $uHost);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$return = curl_exec($ch);
if($return === false)
{
print_r(curl_getinfo($ch));
echo curl_error($ch);
curl_close($ch);
die('Could not connect');
}
else
{
return $ch;
}
}
Disconnect function:
function ftp_disconnect($ch)
{
$return = curl_close($ch);
if($return === false)
{
return "Error: Could not close connection".PHP_EOL;
}
else
{
return $return;
}
}
Function to get the remote file size (in bytes):
function get_rem_file_size($ch, $rem_file)
{
curl_setopt($ch, CURLOPT_INFILE, STDIN);
curl_setopt($ch, CURLOPT_URL, $rem_file);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FTP_CREATE_MISSING_DIRS, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FTPLISTONLY, false);
$return = curl_exec($ch);
if($return === false)
{
print_r(curl_getinfo($ch));
echo curl_error($ch);
curl_close($ch);
die('Could not connect');
}
else
{
$file_header = curl_getinfo($ch);
return $file_header['download_content_length'];
}
}
Upload file function:
function upload_file($ch,$local_file,$remote_file,$resume)
{
echo "attempting to upload $local_file to $remote_file".PHP_EOL;
$file = fopen($local_file, 'rb');
if($resume)
{
curl_setopt($ch, CURLOPT_RESUME_FROM, get_rem_file_size($ch, $remote_file));
}
curl_setopt($ch, CURLOPT_URL, $remote_file);
curl_setopt($ch, CURLOPT_UPLOAD, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FTP_CREATE_MISSING_DIRS, true);
curl_setopt($ch, CURLOPT_INFILE, $file);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($local_file));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$return = curl_exec($ch);
if($return === false)
{
fclose($file);
return curl_error($ch).PHP_EOL;
}
else
{
fclose($file);
echo $local_file.' uploaded'.PHP_EOL;
return true;
}
}
Quick usage example:
$ftp = ftp_getconnect($uName, $pWord, 'ftp://'.$uHost);
$rem_file = 'ftp://'.$uHost.'/path/to/remote/file.ext';
$loc_file = 'path/to/local/file.ext';
$resume = 'true';
$success = upload_file($ftp, $loc_file, $rem_file, $resume);
if($success !== true)
{
//failure
echo $success;
curl_close($ch);
}
print_r(ftp_disconnect($ftp));
Quick note, if there is a large set of files, you can loop through them and upload_file without connecting/disconnecting each time.

Copy img from url to server: no such file or directory

I am using php to get an image from url and copy it to my server but got an error saying there is no such file
Image example:
http://www.google.co.in/intl/en_com/images/srpr/logo1w.png
Here is the solution I am using:
//Get the file
$content = file_get_contents("http://www.google.co.in/intl/en_com/images/srpr/logo1w.png");
//Store in the filesystem.
$fp = fopen("/location/to/save/image.jpg", "w");
fwrite($fp, $content);
fclose($fp);
I am getting the following error. Did i do anything wrong?
fopen(/location/to/save/image.jpg): failed to open stream: No such file or directory
✓ This worked for me.
Try it without the /location/to/save/
The file will be saved in the same folder you run the script in.
Such as:
<?php
//Get the file
$content = file_get_contents("http://www.google.co.in/intl/en_com/images/srpr/logo1w.png");
//Store in the filesystem.
$fp = fopen("image_google.jpg", "w");
fwrite($fp, $content);
fclose($fp);
?>
function download_image($url,$destination_path = '')
{
// CHECKS IF CURL DOES EXISTS. SOMETIMES WEB HOSTING DISABLES FILE GET CONTENTS
if (function_exists('curl_version'))
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
} else
{
$content = file_get_contents($url);
}
// CHECKS IF DIRECTORY DOESNT EXISTS AND DESTINATION PATH IS NOT EMPTY
if(!file_exists($destination_path) && $destination_path != ''){
mkdir($destination_path, 0755, true);
}
// ATTEMPT TO CREATE THE FILE
$fp = fopen($destination_path.'/'.date('YmdHis').".jpg", "a+");
fwrite($fp, $content);
fclose($fp);
}
download_image('http://davidwalsh.name/wp-content/themes/jack/images/treehouse-1.png','images');
The folder (/location/to/save in here) should exist. You also need write permissions in it.

Downloading large files using PHP

I am using following code to download files from some remote server using php
//some php page parsing code
$url = 'http://www.domain.com/'.$fn;
$path = 'myfolder/'.$fn;
$fp = fopen($path, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);
// some more code
but instead of downloading and saving the file in the directory it is showing the file contents (junk characters as file is zip) directly on the browser only.
I guess it might be an issue with header content, but not know exactly ...
Thanks
I believe you need:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
to make curl_exec() return the data, and:
$data = curl_exec($ch);
fwrite($fp, $data);
to get the file actually written.
As mentioned in http://php.net/manual/en/function.curl-setopt.php :
CURLOPT_RETURNTRANSFER: TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly.
So you can simply add this line before your curl_exec line:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
and you will have the content in $data variable.
Use the following function that includes error handling.
// Download and save a file with curl
function curl_dl_file($url, $dest, $opts = array())
{
// Open the local file to save. Suppress warning
// upon failure.
$fp = #fopen($dest, 'w+');
if (!$fp)
{
$err_arr = error_get_last();
$error = $err_arr['message'];
return $error;
}
// Set up curl for the download
$ch = curl_init($url);
if (!$ch)
{
$error = curl_error($ch);
fclose($fp);
return $error;
}
$opts[CURLOPT_FILE] = $fp;
// Set up curl options
$failed = !curl_setopt_array($ch, $opts);
if ($failed)
{
$error = curl_error($ch);
curl_close($ch);
fclose($fp);
return $error;
}
// Download the file
$failed = !curl_exec($ch);
if ($failed)
{
$error = curl_error($ch);
curl_close($ch);
fclose($fp);
return $error;
}
// Close the curl handle.
curl_close($ch);
// Flush buffered data to the file
$failed = !fflush($fp);
if ($failed)
{
$err_arr = error_get_last();
$error = $err_arr['message'];
fclose($fp);
return $error;
}
// The file has been written successfully at this point.
// Close the file pointer
$failed = !fclose($fp);
if (!$fp)
{
$err_arr = error_get_last();
$error = $err_arr['message'];
return $error;
}
}

Categories