This question already has answers here:
Saving image from PHP URL
(11 answers)
Closed 8 years ago.
I want to download images from a web page, for example, www.yahoo.com, and store it in a folder using PHP.
I am getting the page source using file_get_contents() and extracting the img src tag. I am passing this src to cURL code. The code does not give any error, but the images are not getting downloaded. Please check out the code. I am not getting where I am going wrong.
<?php
$html = file_get_contents('www.yahoo.com');
$ptn = '/< *img[^>]*src *= *["\']?([^"\']*)/i';
preg_match_all($ptn, $html, $matches, PREG_PATTERN_ORDER);
$seq = 1;
foreach($matches as $img)
{
$fp = fopen("root/Images/image_$seq.jpg", 'wb');
$ch = curl_init ($img);
curl_setopt($ch,CURLOPT_FILE, $fp);
curl_setopt($ch,CURLOPT_URL, $img);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$image = curl_exec($ch);
curl_close($ch);
fwrite($fp, $image);
fclose($fp);
$seq++;
}
echo "IMAGES DOWNLOADED";
?>
foreach($matches as $img)
should be changed to
foreach($matches[1] as $img)
BTW: you should replace the file_get_contents by cURL, it's about 3x as fast;)
Is $img the full URL of the image?
Is the image protected (use referer)?
$image = false;
$ch = curl_init();
curl_setopt($ch, CURLOPT_REFERER,$url);
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 7);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_ENCODING,gzip);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$image = curl_exec ($ch);
Try debugging first.
First try it with a single image from Yahoo, http://www.depers.nl/beeld/w100/2011/201105/20110510/anp/sport/img-100511-349.onlinebild.jpg.
Also, why use file_get_contents and curl? Use curl instead.
Make a function for cURL: function simple_curl ( $url,$binary=false){ set your cURL vars, return curl_exec).
Get yahoo.com: $result = simple_curl($url);
Get links with the pattern (check if the matches contains the full URL ( domain + directory + file ).
Loop each pattern match (don't forget: multi array!! So loop on $matches[1]).
curl binary file and save it: $image = simple_curl($match,true);
www.yahoo.com is not a URL, http://www.yahoo.com/ is.
$img is an array you need to iterate $matches[1]
You both tell cURL to write to a file and retrieve the result. Use one.
I don't know how you don't see errors. I would look into that. Copying and pasting and then running it gave me plenty of errors.
Related
One of the pages of a website i'm working on should display information about a manga such as it's cover image.
I'm trying to display an image I got by making a curl request.
<?php
if(isset($_GET['info'])) {
$postedData = $_GET["info"]; //json object containing info about manga such as author/title etc.
$info = json_decode($postedData, true);
$mangacoverid = $info['im']; //id of the cover image that i'm getting from json object
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://cdn.mangaeden.com/mangasimg/" . $mangacoverid); //link of API i'm using and adding cover id to it
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$picture = curl_exec($ch);
curl_close($ch);
header('Content-type: image/jpeg');
echo $picture; //displays image in browser
}
?>
-Some 'mangacoverid' for testing purposes:
ff/ff94bb880357b6b811bccbbfd3356c5ec41fbb184291323f0ed6a86a.jpg
c1/c1b0173d8986681f23ecf5a69d26aa9dab4a04db4d40f99bed539198.jpg
0c/0cf6ebf78074e748ab2aeea3a0fcb9e0dd43040974c66e24fa46703f.jpg
5d/5dcfed2e033c2da62e7ac89367533ebbc344373c46a005e274a16785.png
18/18b1f0b13bccb594c6daf296c1f9b6dbd83783bb5ae63fe1716c9091.jpg
35/35bf6095212da882f5d2122fd547800ed993c58956ec39b5a2d52ad4.jpg
-While I am able to display the image in the page, the whole page background becomes black with the image in the middle of the page. (i.e. style="margin: 0px; background: #0e0e0e;>").
What I am trying to do is to insert the image in an HTML tag, so that I can place it somewhere else in the page.
I tried just putting the normal cdn link with 'mangacoverid' attached to it in an tag but the image provider doesn't allow hotlinking and it throws 403 error.
Any help really appreciated!
I tested your code and it seems to be working correctly when the cover ID is hard coded.
Could the issue be that the JSON passed via query param is not getting parsed correctly (due to URL encoding)?
Does it work correctly for you with a cover ID hard coded?
File image.php
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, sprintf('https://cdn.mangaeden.com/mangasimg/%s', $_GET['id']));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$picture = curl_exec($ch);
curl_close($ch);
header('Content-type: image/jpeg');
echo $picture;
And in your script that generates the page displaying the image:
// Assuming $info holds the decoded json for the manga
echo(sprintf('<img src="image.php?id=%s>', $info['im']);
Ok, I'll post the solution in case anyone ever bumps into this.
The code is the mostly the same as original: just edited a few lines as shown below.
-I created a file in the directory called 'tempcover.jpg'.
-I got the image using the function 'imagecreatefromstring($picture)'.
-I saved the image into the file with 'imagejpeg($img,'tempcover.jpg', 100)'.
By doing this I can just refer to the file in the HTML tag and display it the way I want to.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://cdn.mangaeden.com/mangasimg/" . $mangacoverid); //link of API i'm using and adding cover id to it
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$picture = curl_exec($ch);
curl_close($ch);
$img = imagecreatefromstring($picture);
imagejpeg($img,'tempcover.jpg', 100);
?>
<!--HTML-->
<img src="tempcover.jpg" alt="bruh" height="400px" width="300px">
I'm trying do retrieve and download a file (image) from a remote location.
Inside the php.ini the allow_url_fopen is enabled, but i can't download the image.
Code i'm using is described below
$local_file = "test.jpg";
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxxx&pwd=xxxx";
$ch = curl_init();
$fp = fopen ($local_file, 'w+');
$ch = curl_init($remote_file);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_exec($ch);
curl_close($ch);
fclose($fp);
with any other url that contains a real jpg file, it's working perfectly, i suppose that the issue is that the url use some special characters that doesn't like to curl.
If i try to execute the php snippet above,page load for almost 1 minute,and it seems that no error are displayed,the image test.jpg is created, but it's empty.
Do you have any suggestion?
Thanks!
Try this
$local_file = "test.jpg";
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxxx&pwd=xxxx";
function getPage($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
function saveToFile($base, $decode=false, $output_file)
{
$ifp = fopen($output_file, "wb");
if ($decode){
fwrite($ifp, base64_decode($base));
}else{
fwrite($ifp, $base);
}
fclose($ifp);
return($output_file);
}
$remote_page = getPage($remote_file);
$saved_file = saveToFile($remote_page , false, $local_file);
when debugging issues like this, set CURLOPT_VERBOSE, it will probably reveal why the page loaded for almost 1 minute, with no apparent output.
i suppose that the issue is that the url use some special characters - this is fully possible, for example your username and password, they're supposed to be urlencoded. urlencoding is binary safe, meaning you can have any special characters you'd like, you just need to encode it properly. use urlencode() or http_build_query() for that, eg
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?" . http_build_query ( array (
'cmd' => 'snapPicture2',
'usr' => 'username',
'pwd' => 'password'
) );
now http_build_query will properly urlencode any special characters in your username and password (for example, if your username is an email address, the # becomes %40).
if that doesn't fix it, what does CURLOPT_VERBOSE say?
also, final note, here you're sending the download request with credentials in a GET request. that's very unusual, the vast majority of websites want you to login with a POST request, and there are good security-related reasons for that, are you sure your website allows sending credentials in GET parameters? the vast majority of websites doesn't allow it... (and the best way to find out, is to record a browser logging in, does the browser use GET parameters, or POST parameters?)
trying to copy() .MP3 file from remote url but it always fails.
$link = str_replace(' ','%20','http://mp3hungama.com/music/download.php?song_id=80522');
if (!copy($link,'/home2/muser/tmp/newname.mp3')) {
echo 'copy failed !';
}
$link url redirects to http://mp3hungama.com/music/audio//Indian%20Movies/Indian%20Movies%20Hindi%20Mp3%20Songs/Singh%20Is%20Bling%20(2015)/songs/Cinema%20Dekhe%20Mamma%20#%20Mp3HunGama.Com.mp3
same code works for others random urls like www.example.com/download.php?id=2332. what's the specifically problem here or any other way to do this job ?
I've tested your code and I also couldn't download the file, then, I've used curl an it work as expected:
$local_file = "/home2/muser/tmp/newname.mp3";//This is the file where we save the information
$remote_file = "http://mp3hungama.com/music/download.php?song_id=80522"; //Here is the file we are downloading
$ch = curl_init();
$fp = fopen ($local_file, 'w+');
$ch = curl_init($remote_file);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_exec($ch);
curl_close($ch);
fclose($fp);
NOTE:
Make sure /home2/muser/tmp/ has write permissions.
TIP:
In the future, if you need to encode/decode a url, use urlencode or urldecode instead of str_replace
This link
already redirects to second link. So it's working already.
I am doing a system where one of my sites goes to the other to get documents.
On the first site I am using Curl to make a request to get the file wanted:
I am using the solution from Download file from URL using CURL :
function collect_file($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_REFERER, "http://example.com");
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
return($result);
}
function write_to_file($text,$new_filename){
$fp = fopen($new_filename, 'w');
fwrite($fp, $text);
fclose($fp);
}
$curlUrl = 'http://site2.com/file-depository/14R4NP8JkoIHwIyjnexSUmyJibdpHs5ZpFs3NLFCxcs54kNhHj';
$new_file_name = "testfile-new.png";
$temp_file_contents = collect_file($curlUrl);
write_to_file($temp_file_contents,$new_file_name);
I am testing downloading an image. If i use a direct URL into $curlUrl , for instance http://site2.com/file-depository/image.png it works perfect.
What I am doing is that the URL http://site2.com/file-depository/14R4NP8JkoIHwIyjnexSUmyJibdpHs5ZpFs3NLFCxcs54kNhHj is then parsed and checked against a database to match the document requested, once there is a document matched I need to provide this document to the Curl response.
I have tried many ways to read the file but everytime i am getting a file on the other end but it is only 1kb in size (45 expected) and when trying to open it i get an error unkown file type etc.
On the second site, once the URL is validated here is what I have:
$file = readfile('some-image.png');
echo $file;
I am guessing there is part of the information which belongs to the file missing but can't figure it out, any pointers appreciated!
I have replaced
function write_to_file($text,$new_filename){
$fp = fopen($new_filename, 'w');
fwrite($fp, $text);
fclose($fp);
}
by file_put_contents($new_file_name,trim($temp_file_contents));
Please note the trim(), the issue was that I was apparently collecting some empty space in front of the file content.
I have tried to download an image from a PHP link. When I try the link in a browser it downloads the image. I enabled curl and I set “allow_url_fopen” to true. I’ve used the methods discussed here Saving image from PHP URL but it didn’t work. I've tried "file_get_contents" too, but it didn't work.
I made few changes, but still it doesn’t work. This is the code
$URL_path='http://…/index.php?r=Img/displaySavedImage&id=68';
$ch = curl_init ($URL_path);
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);
$fp = fopen($path_tosave.'temp_ticket.jpg','wb');
fwrite($fp, $raw);
fclose($fp);
Do you have any idea to make it works? Please help. Thanks
<?php
if( ini_get('allow_url_fopen') ) {
//set the index url
$source = file_get_contents('http://…/index.php?r=Img/displaySavedImage&id=68');
$filestr = "temp_ticket.jpg";
$fp = fopen($filestr, 'wb');
if ($fp !== false) {
fwrite($fp, $source);
fclose($fp);
}
else {
// File could not be opened for writing
}
}
else {
// allow_url_fopen is disabled
// See here for more information:
// http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen
}
?>
This is what I used to save an image without an extension (dynamic image generated by server). Hope it works for you. Just make sure that the file path location is fully qualified and points to an image. As #ComFreek pointed out, you can use file_put_contents which is the equivalent to calling fopen(), fwrite() and fclose() successively to write data to a file. file_put_contents
You can use it as a function :
function getFile($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$tmp = curl_exec($ch);
curl_close($ch);
if ($tmp != false){
return $tmp;
}
}
And to call it :
$content = getFile(URL);
Or save its content to a file :
file_put_contents(PATH, getFile(URL));
You're missing a closing quote and semicolon on the first line:
$URL_path='http://…/index.php?r=Img/displaySavedImage&id=68';
Also, your URL is in $URL_path but you initialise cURL with $path_img which is undefined based on the code in the question.
Why use cURL when file_get_contents() does the job?
<?php
$img = 'http://…/index.php?r=Img/displaySavedImage&id=68';
$data = file_get_contents( $img );
file_put_contents( 'img.jpg', $data );
?>