I need to save an image from a url using CURL and save it to a folder on my server. I've been battling with this code to no avail. Ideally I'd like to grab the image and save it as "photo1" or something. Help!
function GetImageFromUrl($link)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch,CURLOPT_URL,$link);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
return $result;
}
$sourcecode = GetImageFromUrl($iticon);
$savefile = fopen(' /img/uploads/' . $iconfilename, 'w');
fwrite($savefile, $sourcecode);
fclose($savefile);
try this:
function grab_image($url,$saveto){
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$raw=curl_exec($ch);
curl_close ($ch);
if(file_exists($saveto)){
unlink($saveto);
}
$fp = fopen($saveto,'x');
fwrite($fp, $raw);
fclose($fp);
}
and ensure that in php.ini allow_url_fopen is enable
Option #1
Instead of picking the binary/raw data into a variable and then writing, you can use CURLOPT_FILE option to directly show a file to the curl for the downloading.
Here is the function:
// takes URL of image and Path for the image as parameter
function download_image1($image_url, $image_file){
$fp = fopen ($image_file, 'w+'); // open file handle
$ch = curl_init($image_url);
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // enable if you want
curl_setopt($ch, CURLOPT_FILE, $fp); // output to file
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1000); // some large value to allow curl to run for a long time
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
// curl_setopt($ch, CURLOPT_VERBOSE, true); // Enable this line to see debug prints
curl_exec($ch);
curl_close($ch); // closing curl handle
fclose($fp); // closing file handle
}
And here is how you should call it:
// test the download function
download_image1("http://www.gravatar.com/avatar/10773ae6687b55736e171c038b4228d2", "local_image1.jpg");
Option #2
Now, If you want to download a very large file, that case above function may not become handy. You can use the below function this time for handling a big file. Also, you can print progress(in % or in any other format) if you want. Below function is implemented using a callback function that writes a chunk of data in to the file in to the progress of downloading.
// takes URL of image and Path for the image as parameter
function download_image2($image_url){
$ch = curl_init($image_url);
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // enable if you want
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1000); // some large value to allow curl to run for a long time
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
curl_setopt($ch, CURLOPT_WRITEFUNCTION, "curl_callback");
// curl_setopt($ch, CURLOPT_VERBOSE, true); // Enable this line to see debug prints
curl_exec($ch);
curl_close($ch); // closing curl handle
}
/** callback function for curl */
function curl_callback($ch, $bytes){
global $fp;
$len = fwrite($fp, $bytes);
// if you want, you can use any progress printing here
return $len;
}
And here is how to call this function:
// test the download function
$image_file = "local_image2.jpg";
$fp = fopen ($image_file, 'w+'); // open file handle
download_image2("http://www.gravatar.com/avatar/10773ae6687b55736e171c038b4228d2");
fclose($fp); // closing file handle
If you want to download an image from https:
$output_filename = 'output.png';
$host = "https://.../source.png"; // <-- Source image url (FIX THIS)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $host);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // <-- don't forget this
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // <-- and this
$result = curl_exec($ch);
curl_close($ch);
$fp = fopen($output_filename, 'wb');
fwrite($fp, $result);
fclose($fp);
Improved version of Komang answer (add referer and user agent, check if you can write the file), return true if it's ok, false if there is an error :
public function downloadImage($url,$filename){
if(file_exists($filename)){
#unlink($filename);
}
$fp = fopen($filename,'w');
if($fp){
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$result = parse_url($url);
curl_setopt($ch, CURLOPT_REFERER, $result['scheme'].'://'.$result['host']);
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0');
$raw=curl_exec($ch);
curl_close ($ch);
if($raw){
fwrite($fp, $raw);
}
fclose($fp);
if(!$raw){
#unlink($filename);
return false;
}
return true;
}
return false;
}
This is easiest implement.
function downloadFile($url, $path)
{
$newfname = $path;
$file = fopen($url, 'rb');
if ($file) {
$newf = fopen($newfname, 'wb');
if ($newf) {
while (!feof($file)) {
fwrite($newf, fread($file, 1024 * 8), 1024 * 8);
}
}
}
if ($file) {
fclose($file);
}
if ($newf) {
fclose($newf);
}
}
Related
$camera_ip = "10.10.10.10";
$image_url = "http://$camera_ip/cgi-bin/image.jpg?camera=right&size=1024x768&quality=60";
$ch = curl_init($image_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$rawdata = curl_exec($ch);
curl_close($ch);
$fp = fopen('./logo.jpg', 'wb');
fwrite($fp, $rawdata);
fclose($fp);
A file is being saved at 7KB but the size is 0x0 ... I can't figure out why the file isn't being saved correctly. My guess is that the file isn't being loaded fully before being saved, but is there a way of ensuring that?
Try using "w" instead of "wb" $fp = fopen('./logo.jpg', 'w');
Or try: file_put_contents('./logo.jpg',$rawdata); (not sure it is binary safe, should be)
And
Check your curl result to see what came back.
$info = var_export(curl_getinfo($ch),true);
file_put_contents('log.txt',$info);
OR
header('content-type: text/plain');
var_export(curl_getinfo($ch));
UPDATE
The curl Request failed (returned false).
Now you need to find out WHY.
For now change your:
curl_setopt($ch, CURLOPT_HEADER, 0);
To:
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
Add these options for trouble shooting:
curl_setopt($ch, CURLOPT_ENCODING,"");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_FAILONERROR,true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$data = curl_exec($ch);
if (curl_errno($ch)){
echo ' Retrieve Base Page Error: ' . curl_error($ch);
}
else {
$info = rawurldecode(var_export(curl_getinfo($ch),true));
$skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE));
$responseHeader= substr($data,0,$skip);
$data= substr($data,$skip);
echo "HEADER: $responseHeader\n";
echo "\n\nINFO: $info\n\nDATA: $data";
}
You will likely get the "Retrieve Base Page Error:" but it will also tell WHY it failed. If you cannot echo, replace echo with $info .=
I'm trying to copy images from an array of URLs with the following code. The problem is it only saves the last picture, anyone knows why is this?
foreach($photos['data'] as $photo)
{
echo "guardando:";
echo $photo['id'];
$idFoto++;
$fp = fopen('foto'.$idFoto.'.jpg', 'wb');
curl_setopt($ch, CURLOPT_URL, $photo['source']);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
}
I think your problem is in curl_close($ch), this call should be outside for bucle or maybe you could call curl_init for each photo also could check if curl_setopt is returning true or false:
foreach($photos['data'] as $photo)
{
echo "Guardando $idFoto: $photo['source']\n";
$idFoto++;
$fp = fopen('foto'.$idFoto.'.jpg', 'wb');
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $photo['source']);
//curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
if(curl_exec($ch)===false) echo "Error: ".curl_error()."\n";
fclose($fp);
curl_close($ch);
}
Also note CURLOPT_RETURNTRANSFER is not needed because we are saving to file and not assigning curl_exec return. Could you test please?
i am trying to save a remote image to a file using php curl but the file never get saved! could any one help me how to troublshoot this problem ? the image file never get created and but echo $returned_content has the data!
<?
$returned_content = get_data('http://somesite.com/43534545345dfsdfdsfdsfds.jpg');
echo $returned_content;
$fp = fopen('43534545345dfsdfdsfdsfds.jpg', 'w');
fwrite($fp, $returned_content);
fclose($fp);
/* gets the data from a URL */
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
?>
<?php
$ch = curl_init('http://www.example/2012/09/flower.jpg');
$fp = fopen('/localProject/imagesFolder/newname.jpg', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
?>
Try this
<?php
function getImagen($url, $rename, $ch)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$rawdata=curl_exec ($ch);
curl_close ($ch);
$fp = fopen("$rename.jpg",'w');
fwrite($fp, $rawdata);
fclose($fp);
}
$ch = curl_init();
$image ="http://sampleurl.com/imagen.jpg";
getImagen ($image, "imagen", $ch);
?>
Works 100% :)
I have an url with an image: http://www.example.com/image.jpg
and I have an action in the controller that uploads a file to the server by user input. I want to use this same action to upload a file by url. I started to get the data from image:
$url = "http://www.example.com/image.jpg";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$rawdata=curl_exec($ch);
curl_close ($ch);
Now how do I send the $rawdata to the controller to be handled like a normal user upload?
Thanks
I figured it out myself.
$url = "http://www.example.com/image.jpg";
$filename = basename($url, rand_string(7));
$path = realpath("../webroot/uploads/")."/".$filename;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$rawdata=curl_exec($ch);
curl_close ($ch);
if(file_exists($path)){
unlink($path);
}
$file = fopen($path, 'x');
fwrite($file, $rawdata);
fclose($file);
$post_data['Filedata'] = '#'.$path;
$url = "http://localhost/controller/action";
$ch = curl_init();
// Set URL on which you want to post the Form and/or data
curl_setopt($ch, CURLOPT_URL, $url);
// Data+Files to be posted
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// Pass TRUE or 1 if you want to wait for and catch the response against the request made
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// For Debug mode; shows up any error encountered during the operation
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Execute the request
$response = curl_exec($ch);
echo $response;
In the controller:
function action(){
//get properties of the file
//$_FILES['Filedata']['name'];
//$_FILES['Filedata']['size'];
//$_FILES['Filedata']['tmp_name'];
//savefile();
}
If anyone knows how to post the file without saving it will be great.
I have function to download remote file based on offset and limit.
function get_part_file($url, $offset, $limit){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RANGE, ''.$offset.'-'.$limit.'');
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
I wanna download 1024 bytes from end but this function download whole file. So, how can I do that?
If the remote host does not support Range headers, it doesn't matter what you do: you won't be able to download a specific range.
$ch = curl_init(trim($remoteFile));
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RANGE, '0-102399');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false );
$fp = fopen($filepath, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_exec($ch);
fclose($fp);
curl_close($ch);