I need to save an image from a PHP URL to my PC.
Let's say I have a page, http://example.com/image.php
, holding a single "flower" image, nothing else. How can I save this image from the URL with a new name (using PHP)?
-
1If copying a large quantity or size of files, note that **CURL** methods are preferable (like the 2nd example in the [accepted answer](https://stackoverflow.com/a/724449/8112776)) as **CURL** takes about a third of the time as `file_put_contents` etc. – ashleedawg May 12 '19 at 11:34
11 Answers
If you have allow_url_fopen
set to true
:
$url = 'http://example.com/image.php';
$img = '/my/folder/flower.gif';
file_put_contents($img, file_get_contents($url));
Else use cURL:
$ch = curl_init('http://example.com/image.php');
$fp = fopen('/my/folder/flower.gif', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
-
1Thanks bro, your code help me to solve the problem. But could u pls help me to make the script automated .I mean when a new gif image come to the url (“http://example.com/image.php”) then our script automatically fetch the new image and store it to my directory? – riad Apr 07 '09 at 08:26
-
38
-
2I think riad means using a `$_GET` variable containing the URL of the image `http://example.com/fetch-image.php?url=http://blabla.com/flower.jpg`. In the case of this example, you could just call `$_GET['url']` in your PHP script, like so: `$ch = curl_init($_GET['url']);`. – Mathias Bynens Nov 29 '09 at 13:04
-
I'm curious, if the type of image being generated by the php varies, can you dynamically set the saved image type? How do you tell the type of the generated image? – andrew Jan 18 '11 at 21:23
-
6+1 for being the only answer I've seen that includes the "b" for binary flag. – Will Morgan Oct 17 '12 at 16:12
-
46@vartec: coz it was smoking a cigarette and had a big smile on its face :) – Jimbo May 27 '13 at 20:22
-
1Could you expand on this so that there is a way to compare images already downloaded? Let's say you've downloaded flower.gif in a previous attempt but need to run the script again, I imagine you'd need to compare filesizes - if they are the same, skip the download. – Tony M Jul 19 '13 at 14:18
-
To use this method, you have to set allow_url_fopen to on. The allow_url_fopen directive is disabled by default. You should be aware of the security implications of enabling the allow_url_fopen directive. PHP scripts that can access remote files are potentially vulnerable to arbitrary code injection. When the allow_url_fopen directive is enabled, you can write scripts that open remote files as if they are local files. – Foreever Aug 12 '14 at 06:19
-
1I have used the first solution, it generates the image but image has no data. It says invalid image. Thanks – Mohan Oct 16 '15 at 07:15
-
-
I have asked a simillar question [here](http://stackoverflow.com/questions/36903392/why-file-get-contents-doesnt-work-without-protocol), May you please take a look at it? – stack Apr 28 '16 at 01:34
-
1@Abdukhafiz Most of Chrome's speed is from: using good protocols; creating lots of simultaneous requests; and manipulating process and operating system behaviour to give itself a (n often disproportionately) large share of the processor. – wizzwizz4 Dec 25 '16 at 10:25
-
I've been trying to code with copy($source, $target), but that was slow like dial up connection 2020. and this code is super fast. Thank you sir. – MFarooqi Aug 03 '17 at 17:18
-
-
Some servers block the first method, I encourage people to use cURL method. – Marcelo Agimóvel Nov 12 '18 at 02:01
-
@vartec i have a download link like 'https://sitename/downloads/123123123123123', image could be jpg png etc. How can i save image in folder when image extension is not given in download path? – Muhammad Rohail Dec 10 '19 at 06:42
Use PHP's function copy():
copy('http://example.com/image.php', 'local/folder/flower.jpg');
Note: this requires allow_url_fopen

- 4,505
- 11
- 62
- 88

- 15,731
- 6
- 49
- 56
-
No connection could be made because the target machine actively refused it. :( – jackkorbin Jul 26 '14 at 09:09
-
@jackkorbin is it an IP restriction or something? What happens when you try it in your browser? – Halil Özgür Jul 26 '14 at 15:35
-
3
-
4
-
Scenario: Loading a dynamically generated image from remote server to own server (which serves it to the user). If remote server does not supply the resource, it probably yields a `500 (Internal Server Error)` on your server. – Avatar May 18 '21 at 17:41
-
@Avatar if I understood you correctly and your concern is error handling, this would raise a warning, return false and not save it in case of an unsuccessful HTTP response. Of course, other variants can be more useful depending on the use case and requirements. – Halil Özgür May 19 '21 at 10:02
$content = file_get_contents('http://example.com/image.php');
file_put_contents('/my/folder/flower.jpg', $content);

- 73,842
- 19
- 118
- 155
-
The page is holding an animated gif image. A file is stored into the folder as flower.gif .But it is blank.No image show.any solution? – riad Apr 07 '09 at 07:07
-
Turn on error_reporting(E_ALL|E_STRICT) and check the return value of file_get_contents(), then you should get a reasonable error message. – soulmerge Apr 07 '09 at 07:12
-
Perhaps the site admin has forbidden outside referrals. In that case you can try stream_context_create() and set the appropriate HTTP headers. http://us2.php.net/manual/en/function.stream-context-create.php – Calvin Apr 07 '09 at 07:18
-
urlencode('http://example.com/image.php') == 'http%3A%2F%2Fexample.com%2Fimage.php', obviously not what you want. Also file is binary, proper flag needs to be set. – vartec Apr 07 '09 at 07:19
-
thanks for the urlencode() hint. As for the binary flag: That one is available in PHP 6 only. – soulmerge Apr 07 '09 at 07:23
-
Thanks all, it’s working fine now. But can anybody help me to do it automated. I mean when a new image come that URL 'http://example.com/image.php' my script will automatically fetch the image and store it to my directory? – riad Apr 07 '09 at 08:19
-
This is another question and it had been asked some days ago on SO, just try to search it. – soulmerge Apr 07 '09 at 11:58
-
5Bit of an old thread... but don't forget file permissions for the directory you are saving into. Just wasted ten minutes forgetting the obvious. – Squiggs. Nov 23 '10 at 09:28
Vartec's answer with cURL didn't work for me. It did, with a slight improvement due to my specific problem.
e.g.,
When there is a redirect on the server (like when you are trying to save the facebook profile image) you will need following option set:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
The full solution becomes:
$ch = curl_init('http://example.com/image.php');
$fp = fopen('/my/folder/flower.gif', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
fclose($fp);
-
2thanks zuul, really & stoe really found helpful after more search or spend time – Rakesh Sharma Dec 13 '12 at 11:33
-
brilliant - that has helped so much! Should be noted on the Vartecs answer too – Nick Jan 18 '14 at 12:15
-
I look forward to trying this code out! Looks like it might be the answer to CORS measures I've been running into since 2020. – Eric Hepperle - CodeSlayer2010 Dec 11 '22 at 12:36
Here you go, the example saves the remote image to image.jpg.
function save_image($inPath,$outPath)
{ //Download images from remote server
$in= fopen($inPath, "rb");
$out= fopen($outPath, "wb");
while ($chunk = fread($in,8192))
{
fwrite($out, $chunk, 8192);
}
fclose($in);
fclose($out);
}
save_image('http://www.someimagesite.com/img.jpg','image.jpg');

- 19,231
- 14
- 60
- 80
-
The guys url is http://example.com/image.php. Notice that it is a php generated image an not a simple jpeg. – andrew Jan 18 '11 at 21:14
-
10How is the generation of the image or the files extension at all relevant to the question? – Sam Becker Jan 19 '11 at 10:33
-
-
@SamThompson from the [PHP documentation](http://php.net/manual/en/function.fread.php) it means chunk size (usually 8192). – Daan Mar 02 '16 at 09:09
-
AFAIK fread may return shorter chunk than requested 8K. Don't you need to calculate effective chunk length for fwrite? – Sergey Jun 25 '18 at 16:57
I wasn't able to get any of the other solutions to work, but I was able to use wget:
$tempDir = '/download/file/here';
$finalDir = '/keep/file/here';
$imageUrl = 'http://www.example.com/image.jpg';
exec("cd $tempDir && wget --quiet $imageUrl");
if (!file_exists("$tempDir/image.jpg")) {
throw new Exception('Failed while trying to download image');
}
if (rename("$tempDir/image.jpg", "$finalDir/new-image-name.jpg") === false) {
throw new Exception('Failed while trying to move image file from temp dir to final dir');
}

- 227,796
- 193
- 515
- 708
-
this solution was also the only one that worked for me. Thank you Andrew! – sentinel777 Dec 22 '19 at 15:56
See file()
PHP Manual:
$url = 'http://mixednews.ru/wp-content/uploads/2011/10/0ed9320413f3ba172471860e77b15587.jpg';
$img = 'miki.png';
$file = file($url);
$result = file_put_contents($img, $file)
$data = file_get_contents('http://example.com/image.php');
$img = imagecreatefromstring($data);
imagepng($img, 'test.png');

- 113
- 8
$img_file='http://www.somedomain.com/someimage.jpg'
$img_file=file_get_contents($img_file);
$file_loc=$_SERVER['DOCUMENT_ROOT'].'/some_dir/test.jpg';
$file_handler=fopen($file_loc,'w');
if(fwrite($file_handler,$img_file)==false){
echo 'error';
}
fclose($file_handler);

- 3,789
- 2
- 34
- 38

- 41
- 1
None of the answers here mention the fact that a URL image can be compressed (gzip), and none of them work in this case.
There are two solutions that can get you around this:
The first is to use the cURL method and set the curl_setopt CURLOPT_ENCODING, ''
:
// ... image validation ...
// Handle compression & redirection automatically
$ch = curl_init($image_url);
$fp = fopen($dest_path, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
// Exclude header data
curl_setopt($ch, CURLOPT_HEADER, 0);
// Follow redirected location
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
// Auto detect decoding of the response | identity, deflate, & gzip
curl_setopt($ch, CURLOPT_ENCODING, '');
curl_exec($ch);
curl_close($ch);
fclose($fp);
It works, but from hundreds of tests of different images (png, jpg, ico, gif, svg), it is not the most reliable way.
What worked out best is to detect whether an image url has content encoding (e.g. gzip):
// ... image validation ...
// Fetch all headers from URL
$data = get_headers($image_url, true);
// Check if content encoding is set
$content_encoding = isset($data['Content-Encoding']) ? $data['Content-Encoding'] : null;
// Set gzip decode flag
$gzip_decode = ($content_encoding == 'gzip') ? true : false;
if ($gzip_decode)
{
// Get contents and use gzdecode to "unzip" data
file_put_contents($dest_path, gzdecode(file_get_contents($image_url)));
}
else
{
// Use copy method
copy($image_url, $dest_path);
}
For more information regarding gzdecode see this thread. So far this works fine. If there's anything that can be done better, let us know in the comments below.

- 187
- 11
Create a folder named images located in the path you are planning to place the php script you are about to create. Make sure it has write rights for everybody or the scripts won't work ( it won't be able to upload the files into the directory).

- 19
- 1