0

I have been using the following function to download pictures from a distributor for use on our website as was described here:

$url = "http://covers.stl-distribution.com/7819/lg-9781936417445.jpg";
$itemnum = 80848;
$path = "www.gullions.com/localstore/test/test.jpg";
header('Content-type: image/jpeg');
$ch = curl_init($url); 
$fp = fopen("http://www.gullions.com/localstore/test/test.jpg", 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
fclose($fp);

Instead of downloading and saving the picture, it only prints crazy characters to the screen. I know that means that for some reason the browser is trying to render the picture but most likely doesn't recognize the file type. But I can't seem to find the problem. You can see the crazy output by navigating here. To verify that the image wasn't downloaded and saved, you can navigate here. Also, FTP also shows that no file was downloaded. If you navigate to the original picture's download url you'll see that the file we are trying to download does in fact exist.

I have contacted my host and verified that no settings have been changed with the server, that cURL is functioning properly, and have even rolled back my browser to verify that a recent update didn't cause the issue. I created a test file by removing the function from the application and have tried running it separately but have only had the same results.

Community
  • 1
  • 1
taseaford
  • 45
  • 9

2 Answers2

3

Add:

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

as by default this parameter is false. Docs read:

TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly.

EDIT

Setting CURLOPT_RETURNTRANSFER make curl_exec() return data, so it should be written manually, like this:

$url = "http://covers.stl-distribution.com/7819/lg-9781936417445.jpg";
$ch = curl_init($url);
$fp = fopen("./test.jpg", 'wb');
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_HEADER, 0);
fwrite($fp, curl_exec($ch));
curl_close($ch);
fclose($fp);

Also this code, that uses CURLOPT_FILE works for me just fine:

$url = "http://covers.stl-distribution.com/7819/lg-9781936417445.jpg";
$ch = curl_init($url);
$fp = fopen("./test.jpg", 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);

so I basically suspect that your file handle is not valid, therefore cURL falls back to default output. Try this code with elementary error checking (you should ALWAYS check for errors):

$url = "http://covers.stl-distribution.com/7819/lg-9781936417445.jpg";
$fp = fopen("./test.jpg", 'wb');
if( $fp != null ) {
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_FILE, $fp);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_exec($ch);
  curl_close($ch);
  fclose($fp);
} else {
  exit('ERROR: Failed to open file');
}

Note that my examples write to the same folder scripts sits in. It must work unless your server got file permissions messed badly. If it works for you, then investigate if (usually) user your scripts runs as can write to your target folder.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
  • No luck. The image still isn't saving. Thanks for your suggestion though. – taseaford Jul 12 '13 at 19:09
  • @taseaford, would you mind updating the answer with your new script? By applying both solutions you have now a script that *does not output data* (but instead "returns it as a value"), and I'm really curious to see how this results in a file being created on the disk (the URL you supplied still returns 404 Error). – LSerni Jul 12 '13 at 19:25
  • @lserni: you should not update questions - that's what answers are for. Not sure what you mean by `curious to see how this results in a file created on the dist`. Well, as you said - it results in a file being created on disk, what confuses you here? – Marcin Orlowski Jul 12 '13 at 19:25
  • Sorry, you are correct. @taseaford, can you **add** the new script to the question text? – LSerni Jul 12 '13 at 19:27
  • what for? you got these scripts in multiple variants in my answer. – Marcin Orlowski Jul 12 '13 at 19:27
  • @MarcinOrlowski, well, it's just that I didn't expect this to create anything on the disk - I would have thought that you *either* outputted the data on a file descriptor, *or* you returned it from curl. Anyway, I still don't see how having the data returned by a function can make that function start writing the data on the disk. So I'd like to have the final program code to play with it by myself, that's all. – LSerni Jul 12 '13 at 19:30
  • @MarcinOrlowski, yes, now I have read your updated answer. I agree with it fully. +1, and I'll probably delete my own answer as redundant. – LSerni Jul 12 '13 at 19:32
  • @Iserni instead of modifying my original file, I uploaded a new one [link](http://www.gullions.com/localstore/modules/stlimportmodule/test2.php). As you indicated, it doesn't display the file, but it does save it as you can see here [link](http://www.gullions.com/localstore/modules/stlimportmodule/test.jpg). – taseaford Jul 12 '13 at 19:33
  • @taseaford, just out of curiosity, what would have happened if you had replaced "$path/test.jpg" with just "test.jpg" in your original script, the very first one? Without any other modifications? – LSerni Jul 12 '13 at 19:37
  • @Iserni I get the following error `The image "http://www.gullions.com/localstore/modules/stlimportmodule/test4.php" cannot be displayed because it contains errors. – taseaford Jul 12 '13 at 19:40
  • Heh. I was half hoping it wouldn't. I had something like this happen to me once, and never could properly investigate it. When I hear PHP and cURL, the old wound itches :-) – LSerni Jul 12 '13 at 19:42
  • @taseaford, sorry, of course. You also need to remove the `Header` instruction. But is the image created? Or does nothing happen, without explanation? – LSerni Jul 12 '13 at 19:44
  • @Iserni The fun part will be putting it all back together. This was just one part of the script. I had narrowed it down and found that this was the problem. Hopefully, its the only one.... – taseaford Jul 12 '13 at 19:45
  • @Iserni, I had forgotten to remove the header. Once I removed that it worked like a charm. – taseaford Jul 12 '13 at 19:47
2

You haven't told your browser what type of file to expect, so it's probably defaulting to text/plain.

You need at least:

header('Content-type: image/jpeg');

As well, curl by default outputs whatever it fetches, unless you explicitly tell it you want to have the fetched data returned, or saved directly to file.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • Thanks! That got rid of the junk, but it still isn't saving. I'll move on to try the other suggestions. – taseaford Jul 12 '13 at 19:08
  • 1
    look at Marcin Orlowski's answer below. that'll make curl_exec return the fetched data, which you capture with `$data = curl_exec($ch);`. – Marc B Jul 12 '13 at 19:09
  • This still doesn't solve his original problem - saving the data to a file. That the "saving" script does not output a `image/jpeg` header actually seems OK to me... – LSerni Jul 12 '13 at 19:23