Saving image from PHP URL
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)?
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.
11 Answers 11
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));
$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);
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?
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’]); .
copy('http://example.com/image.php', 'local/folder/flower.jpg');
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.
$content = file_get_contents('http://example.com/image.php'); file_put_contents('/my/folder/flower.jpg', $content);
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?
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.
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
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.
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.
Vartec’s answer with cURL didn’t work for me. It did, with a slight improvement due to my specific problem.
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);
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.
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');
AFAIK fread may return shorter chunk than requested 8K. Don’t you need to calculate effective chunk length for fwrite?
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)
$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);
$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');
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.
Сохранение файла, загруженного на сервер с помощью PHP
Эта статья о некоторых задачах, возникающих при сохранении файла на сервере, при получении его от пользователя через форму ().
Определимся с требованиями. Технически, решение нужно в виде функции, которая принимает набор параметров:
- Данные о загруженном файле;
- Место, где файл должен быть сохранен (директория);
- Флаг — можно ли перезаписать файл, если он уже существует в указанном месте;
- Путь к прежней версии загружаемого файла, чтобы удалить её.
$oldFile — путь к старой версии (относительно $_SERVER[‘DOCUMENT_ROOT’]), укажите если хотите удалить её
if ( ! empty ( $ oldFile ) && $destination != get_canonical_path($_SERVER[‘DOCUMENT_ROOT’] . $oldFile) )
$ result = substr ( $ destination , strlen ( get_canonical_path ( $ _SERVER [ ‘DOCUMENT_ROOT’ ] ) ) ) ;
Выглядит просто, но, возможно, вы обратили внимание на функцию get_canonical_path, которая в PHP отсутствует. Её можно заменить на realpath в некоторых случаях, но чаще всего в реальных приложениях с такой заменой uploadFile работать не будет.
Область применения realpath ограничивается не только существующими файлами, но и не допустимостью использования symbolic links. На практике же, «тяжелые» папки с юзер файлами обычно монтируют на отдельные носители.
Функция вернет путь к файлу (относительно $_SERVER[‘DOCUMENT_ROOT’]) или false, если сохранить файл не удалось.
Задачи, которые решает uploadFile
- Использует канонизацию путей, и таким образом решает проблемы с использованием не канонических путей;
- Создаёт папки (подпапки), если требуется;
- Способно найти не занятое имя файла, чтобы не повредить уже сохраненные файлы;
- Удалит старую версию файла, чтобы не накапливать мусор (но вам нужно предоставить название этого файла).
В функции есть набросок проверки файла по типу: