I'm trying to download a zip file from a server I host and store it on another server using PHP and cURL. My PHP looks like this:
set_time_limit( 0 );
$ci = curl_init();
curl_setopt_array( $ci, array(
CURLOPT_FILE => '/directory/images.zip', // File Destination
CURLOPT_TIMEOUT => 3600, // Timeout
CURLOPT_URL => 'http://example.com/images/images.zip' // File Location
) );
curl_exec( $ci );
curl_close( $ci );
Whenever I run this I get the following error on the CURLOPT_URL line:
Warning: curl_setopt_array(): supplied argument is not a valid File-Handle resource in ...
If I visit the File Location directly in my browser, it downloads. Do I need to pass some kind of header information so that it knows to that it's a zip file? Is there some kind of way I can debug this?
Your problem is that you have to pass a filehandle to CURLOPT_FILE, not the filepath. Here is a working example
$ci = curl_init();
$url = "http://domain.com/images/images.zip"; // Source file
$fp = fopen("/directory/images.zip", "w"); // Destination location
curl_setopt_array( $ci, array(
CURLOPT_URL => $url,
CURLOPT_TIMEOUT => 3600,
CURLOPT_FILE => $fp
));
$contents = curl_exec($ci); // Returns '1' if successful
curl_close($ci);
fclose($fp);
Related
So I have written an Ajax call to download a file after clicking on download button so when I hit the API that I was using to get a file over CURL call which returns the file resource stream so if its a pdf then its fine i am using fopen and fwrite to write the data into a file and its working but when i try to get .gz file stream its not working i mean the .gz file is created but its nothing in that file also when i try to extract it gives me error i am using ubuntu 18.04 and Codeigniter 3
private function __curl(
$url,
$request = "POST",
$data = [],
$header = ["Content-Type: application/json"]
) {
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $this->apiUrl . $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => $request,
CURLOPT_POSTFIELDS => !empty($data) ? json_encode($data) : "",
CURLOPT_HTTPHEADER => $header,
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
return $err;
} else {
$path = "path/to/file/".$fileName;
$fp = fopen($path, 'w');
fwrite($fp, $response);
fclose($fp);
}
}
so I am using this function to call the api and i get the .gz file as a response stream and I want to convert that stream to a as it .gz file with data in it and save it in given path.
You can download a .gz file using curl in php by using the following code:
<?php
// Initialize cURL session
$ch = curl_init();
// Set the URL of the file to be downloaded
curl_setopt($ch, CURLOPT_URL, 'http://example.com/file.gz');
// Set cURL to return the contents of the file as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Execute cURL session and store the contents of the file into a variable
$data = curl_exec($ch);
// Close cURL session
curl_close($ch);
// Write data to local file
$fp = fopen('file.gz', 'w');
fwrite($fp, $data);
// Close local file handle
fclose($fp); ?>
I'm getting the following error when running a script. The error message is as follows...
Warning: file_get_contents() [function.file-get-contents]: https:// wrapper is disabled in the server configuration by allow_url_fopen=0 in /home/satoship/public_html/connect.php on line 22
I know this is a server issue but what do I need to do to the server in order to get rid of the above warning?
#blytung Has a nice function to replace that function
<?php
$url = "http://www.example.org/";
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$contents = curl_exec($ch);
if (curl_errno($ch)) {
echo curl_error($ch);
echo "\n<br />";
$contents = '';
} else {
curl_close($ch);
}
if (!is_string($contents) || !strlen($contents)) {
echo "Failed to get contents.";
$contents = '';
}
echo $contents;
?>
If you do not have the ability to modify your php.ini file, use cURL:
PHP Curl And Cookies
Here is an example function I created:
function get_web_page( $url, $cookiesIn = '' ){
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => true, //return headers in addition to content
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
CURLINFO_HEADER_OUT => true,
CURLOPT_SSL_VERIFYPEER => true, // Validate SSL Cert
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_COOKIE => $cookiesIn
);
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$rough_content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header_content = substr($rough_content, 0, $header['header_size']);
$body_content = trim(str_replace($header_content, '', $rough_content));
$pattern = "#Set-Cookie:\\s+(?<cookie>[^=]+=[^;]+)#m";
preg_match_all($pattern, $header_content, $matches);
$cookiesOut = implode("; ", $matches['cookie']);
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['headers'] = $header_content;
$header['content'] = $body_content;
$header['cookies'] = $cookiesOut;
return $header;
}
NOTE: In revisiting this function I noticed that I had disabled SSL checks in this code. That is generally a BAD thing even though in my particular case the site I was using it on was local and was safe. As a result I've modified this code to have SSL checks on by default. If for some reason you need to change that, you can simply update the value for CURLOPT_SSL_VERIFYPEER, but I wanted the code to be secure by default if someone uses this.
Use this code in your php script (first lines)
ini_set('allow_url_fopen',1);
Edit your php.ini, find allow_url_fopen and set it to allow_url_fopen = 1
Using relative instead of absolute file path solved the problem for me.
I had the same issue and setting allow_url_fopen=on
did not help. This means for instance :
use
$file="folder/file.ext";
instead of
$file="https://website.com/folder/file.ext";
in
$f=fopen($file,"r+");
THIS IS A VERY SIMPLE PROBLEM
Here is the best method for solve this problem.
Step 1 : Login to your cPanel (http://website.com/cpanel OR http://cpanel.website.com).
Step 2 : SOFTWARE -> Select PHP Version
Step 3 : Change Your Current PHP version : 5.6
Step 3 : HIT 'Set as current' [ ENJOY ]
I'm currently working on copying a file from localhost to a remote server using PHP cURL.
I have two separate files, one for the localhost which sends the file, and another for the remote server to receive the file and save it to the server. The codes are as follows :
send.php
<?PHP
$web_page_to_send = "http://admin123.unaux.com/receive.php";
$file_name_with_full_path = "test.jpg";
$post_request = array
(
"sender" => "tmp",
"file" => curl_file_create($file_name_with_full_path)
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $web_page_to_send);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_request);
$result = curl_exec($ch);
curl_close($ch);
echo "<br>Result: ".$result;
?>
receive.php
<?PHP
if(isset($_POST['sender']))
{
echo "got it !";
$file_name = "tmp/".$_POST['sender']."-".$_FILES['file']['name'];
move_uploaded_file($_FILES['file']['tmp_name'], $file_name);
echo "Successful Attempt! <br><br>Filename: ".$file_name;
echo '<br><br> <img src="'.$file_name.'" width="300px"></img>';
}
else
{
echo 'Unauthorized Access!';
}
?>
The codes are working fine on localhost, but after placing the receive.php to the remote server, the file is no more sent and displayed. "http://admin123.unaux.com/receive.php" is where the file is on the remote server. I'm using profreehost free server as the remote server.
Remote server folder structure : Remote Server File and Folder Structure
Can anyone please help me with this problem?
Thank you.
Please get all received data in the receive.php file as below:
$post_data = trim(file_get_contents("php://input"));
after this, try to print $post_data. If you will get null value then response is not hitting at your file.
Try to send above data with below code:
$web_page_to_send = "http://admin123.unaux.com/receive.php";
$file_name_with_full_path = "test.jpg"; // Please write here full file path in the system
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $web_page_to_send,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 20,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => array('sender' => 'tmp','file'=>new CURLFILE($file_name_with_full_path)),
CURLOPT_HTTPHEADER => array(
"Content-Type: image/jpg"
),
CURLOPT_UPLOAD=>true,
));
$response = curl_exec($curl);
$http_response = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
I found this function that does an AWESOME job (IMHO): http://nadeausoftware.com/articles/2007/06/php_tip_how_get_web_page_using_curl
/**
* Get a web file (HTML, XHTML, XML, image, etc.) from a URL. Return an
* array containing the HTTP server response header fields and content.
*/
function get_web_page( $url )
{
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_USERAGENT => "spider", // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
);
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}
The only problem I have is that it doesn't work for https://. Anny ideas what I need to do to make this work for https? Thanks!
Quick fix, add this in your options:
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false)
Now you have no idea what host you're actually connecting to, because cURL will not verify the certificate in any way. Hope you enjoy man-in-the-middle attacks!
Or just add it to your current function:
/**
* Get a web file (HTML, XHTML, XML, image, etc.) from a URL. Return an
* array containing the HTTP server response header fields and content.
*/
function get_web_page( $url )
{
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_USERAGENT => "spider", // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
CURLOPT_SSL_VERIFYPEER => false // Disabled SSL Cert checks
);
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}
I was trying to use CURL to do some https API calls with php and ran into this problem. I noticed a recommendation on the php site which got me up and running: http://php.net/manual/en/function.curl-setopt.php#110457
Please everyone, stop setting CURLOPT_SSL_VERIFYPEER to false or 0. If
your PHP installation doesn't have an up-to-date CA root certificate
bundle, download the one at the curl website and save it on your
server:
http://curl.haxx.se/docs/caextract.html
Then set a path to it in your php.ini file, e.g. on Windows:
curl.cainfo=c:\php\cacert.pem
Turning off CURLOPT_SSL_VERIFYPEER allows man in the middle (MITM)
attacks, which you don't want!
Another option like Gavin Palmer answer is to use the .pem file but with a curl option
download the last updated .pem file from https://curl.haxx.se/docs/caextract.html and save it somewhere on your server(outside the public folder)
set the option in your code instead of the php.ini file.
In your code
curl_setopt($ch, CURLOPT_CAINFO, $_SERVER['DOCUMENT_ROOT'] . "/../cacert-2017-09-20.pem");
NOTE: setting the cainfo in the php.ini like #Gavin Palmer did is better than setting it in your code like I did, because it will save a disk IO every time the function is called, I just make it like this in case you want to test the cainfo file on the fly instead of changing the php.ini while testing your function.
One important note, the solution mentioned above will not work on local host, you have to upload your code to server and then it will work. I was getting no error, than bad request, the problem was I was using localhost (test.dev,myproject.git). Both solution above work, the solution that uses SSL cert is recommended.
Go to https://curl.haxx.se/docs/caextract.html, download the latest cacert.pem. Store is somewhere (not in public folder - but will work regardless)
Use this code
".$result;
//echo "Path:".$_SERVER['DOCUMENT_ROOT'] . "/ssl/cacert.pem";
// this is for troubleshooting only ?>
Upload the code to live server and test.
I need to import a JSON file to a (local) SOLR host with PHP.
I'm trying to use the php cUrl to send something but I'm not that well in php.
My Code for sending a request to get a result from solr already worked:
// ...
$url = 'http://localhost:8983/solr/select?q="test"~1&wt=json&indent=true&start=0&rows=2000';
$curl = curl_init();
// set cUrl options
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array("Content-type:application/json"),
CURLOPT_URL => $url,
CURLOPT_USERPWD => "$login:password"
));
$contents = curl_exec($curl);
$data = json_decode($contents, true);
$docs = $data['response']['docs'];
// ...
But how can I import/index a JSON file to my solr host with cUrl?