439

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)?

1
  • 1
    If copying a large quantity or size of files, note that CURL methods are preferable (like the 2nd example in the accepted answer) as CURL takes about a third of the time as file_put_contents etc.
    – ashleedawg
    Commented May 12, 2019 at 11:34

11 Answers 11

778

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);
16
  • 1
    Thanks 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 (“example.com/image.php”) then our script automatically fetch the new image and store it to my directory?
    – riad
    Commented Apr 7, 2009 at 8:26
  • 38
    And how do you know, that the new image "came"?
    – vartec
    Commented Apr 7, 2009 at 8:37
  • 2
    I 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']);. Commented Nov 29, 2009 at 13:04
  • 6
    +1 for being the only answer I've seen that includes the "b" for binary flag. Commented Oct 17, 2012 at 16:12
  • 47
    @vartec: coz it was smoking a cigarette and had a big smile on its face :)
    – Jimbo
    Commented May 27, 2013 at 20:22
281

Use PHP's function copy():

copy('http://example.com/image.php', 'local/folder/flower.jpg');

Note: this requires allow_url_fopen

6
  • No connection could be made because the target machine actively refused it. :(
    – jackkorbin
    Commented Jul 26, 2014 at 9:09
  • @jackkorbin is it an IP restriction or something? What happens when you try it in your browser? Commented Jul 26, 2014 at 15:35
  • 3
    if target folder doesn't exist, will it automatically created?
    – Monnster
    Commented Jul 10, 2015 at 15:00
  • 4
    @Monnster, no, it won't for normal filesystems. Commented Jul 11, 2015 at 23:43
  • 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
    Commented May 18, 2021 at 17:41
82
$content = file_get_contents('http://example.com/image.php');
file_put_contents('/my/folder/flower.jpg', $content);
8
  • 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
    Commented Apr 7, 2009 at 7: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
    Commented Apr 7, 2009 at 7:12
  • Perhaps the site admin has forbidden outside referrals. In that case you can try stream_context_create() and set the appropriate HTTP headers. us2.php.net/manual/en/function.stream-context-create.php
    – Calvin
    Commented Apr 7, 2009 at 7:18
  • urlencode('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
    Commented Apr 7, 2009 at 7:19
  • 5
    Bit 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.
    Commented Nov 23, 2010 at 9:28
33

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);
3
  • 2
    thanks zuul, really & stoe really found helpful after more search or spend time Commented Dec 13, 2012 at 11:33
  • brilliant - that has helped so much! Should be noted on the Vartecs answer too
    – Nick
    Commented Jan 18, 2014 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. Commented Dec 11, 2022 at 12:36
30

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');
5
  • The guys url is example.com/image.php. Notice that it is a php generated image an not a simple jpeg.
    – andrew
    Commented Jan 18, 2011 at 21:14
  • 10
    How is the generation of the image or the files extension at all relevant to the question?
    – Sam Becker
    Commented Jan 19, 2011 at 10:33
  • fopen needs allow_url_fopen=1 too
    – zloctb
    Commented Sep 18, 2013 at 12:04
  • @SamThompson from the PHP documentation it means chunk size (usually 8192).
    – Daan
    Commented Mar 2, 2016 at 9:09
  • AFAIK fread may return shorter chunk than requested 8K. Don't you need to calculate effective chunk length for fwrite?
    – Sergey
    Commented Jun 25, 2018 at 16:57
10

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');
}
1
  • this solution was also the only one that worked for me. Thank you Andrew! Commented Dec 22, 2019 at 15:56
4
$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);
4

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)
1
  • 2
    need allow_url_fopen = On
    – zloctb
    Commented Sep 18, 2013 at 12:12
4
$data = file_get_contents('http://example.com/image.php');
$img = imagecreatefromstring($data);
imagepng($img, 'test.png');
0
4

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.

0
1

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).

Not the answer you're looking for? Browse other questions tagged or ask your own question.