Page 1 of 1
Save a remote image on my server...
Posted: Sat Jun 25, 2005 6:33 pm
by is_blank
Hello! I'm a first-time poster, and (relative) PHP newbie. I've got a web site I run for my high school students, and I'm looking for a way to reproduce the Wikipedia picture of the day in a sidebar on my front page. (I believe, with proper links back, etc. that should be ok, under fair use and GPL, yes?)
I can handle all of the grabbing and parsing necessary, but I'd like to temporarily store the image on my server, so I can shrink it with imagemagick (they need to be 188px wide). That picture will then link back to the Wikipedia page.
So the plan is to grab the image (once a day, only; I'll run the script as a cron job), and save it to my own directory with a filename like 'potd.jpg' and then overwrite it the next day with the new image.
I've already got a script that grabs the image url; they look something like:
http://upload.wikimedia.org/wikipedia/c ... ager_1.jpg
So what's the best way to simply save that image as potd.jpg on my server? Can it be done?
Posted: Sat Jun 25, 2005 6:53 pm
by nigma
I'd use
fopen to open two streams -- one for reading the remote image, one for writing it locally -- and then use
fread &
fwrite to copy the image.
Look something like:
Code: Select all
$remoteCopy = fopen(REMOTE_PATH,'rb'); // open remote image for reading in binary mode
$localCopy = fopen(LOCAL_PATH,'wb'); // open/create local file for writing in binary mode
// put the contents of $remoteCopy in $localCopy
fwrite($localCopy, fread($remoteCopy,filesize($remoteCopy)));
// close both streams
fclose($remoteCopy);
fclose($localCopy);
Untested, but regardless of what the working version looks like the logic here will hold true.
Posted: Sat Jun 25, 2005 7:49 pm
by is_blank
Hm. I'm gettting some errors I don't understand. First of all, for simplicity's sake, I hardcoded some values:
Code: Select all
$remoteCopy = fopen('http://upload.wikimedia.org/wikipedia/commons/thumb/0/04/300px-Jupiter_from_Voyager_1.jpg','rb'); // open remote image for reading in binary mode
$localCopy = fopen('potd.jpg','wb'); // open/create local file for writing in binary mode
// put the contents of $remoteCopy in $localCopy
fwrite($localCopy, fread($remoteCopy,filesize($remoteCopy)));
// close both streams
fclose($remoteCopy);
fclose($localCopy);
That's giving me the following errors:
Code: Select all
Warning: filesize(): Stat failed for Resource id #5 (errno=2 - No such file or directory) in /home/ferrellw/public_html/php/picotd.php on line 49
Warning: fread(): Length parameter must be greater than 0. in /home/ferrellw/public_html/php/picotd.php on line 49
Line 49 is the fwrite() line. Is it not able to read the remote file?
Posted: Sat Jun 25, 2005 8:34 pm
by nigma
Here's a function you can use in place of filesize() that will work with remote files:
Code: Select all
function remoteFilesize($fp) {
$temp = "e;"e;;
while (!feof($fp)) $temp .= fread($fp,1024);
return strlen($temp);
}
Once you've got that function in your code all you have to do is change the second argument of fread to call remoteFilesize() instead of filesize().
Posted: Sat Jun 25, 2005 9:02 pm
by is_blank
Wow. Thanks for all your help! It's not complaining anymore, but it's creating a file called picotd.jpg that's 0 bytes. I'm not sure what I should check next. I see what everything's doing--where could the hole be?
Posted: Sat Jun 25, 2005 9:36 pm
by nigma

The following
will work. Sorry about previous.
Code: Select all
<?php
$remoteCopy = fopen('http://upload.wikimedia.org/wikipedia/commons/thumb/0/04/300px-Jupiter_from_Voyager_1.jpg','rb'); // open remote image for reading in binary mode
$localCopy = fopen('potd.jpg','wb'); // open/create local file for writing in binary mode
// put the contents of $remoteCopy in $localCopy
while (!feof($remoteCopy)) {
fwrite($localCopy, fread($remoteCopy, 8192));
}
// close both streams
fclose($remoteCopy);
fclose($localCopy);
?>
Posted: Sat Jun 25, 2005 9:54 pm
by is_blank
Beautiful! That does the trick! No need for

; you saved me hours of

!
One question: why "fread($remoteCopy, 8192));"? Do I really want "fread($remoteCopy, remoteFilesize($remoteCopy))" there, or is there a reason for 8192?
Posted: Sun Jun 26, 2005 6:57 am
by Chris Corbyn
is_blank wrote:Beautiful! That does the trick! No need for

; you saved me hours of

!
One question: why "fread($remoteCopy, 8192));"? Do I really want "fread($remoteCopy, remoteFilesize($remoteCopy))" there, or is there a reason for 8192?
Not sure on the 8192 but I do know that you can cut out alot of that hassle with the nice handy
file_get_contents() function

- it does all that for you (I assume).
Code: Select all
function downloadFile($remote, $local) {
if($data = @file_get_contents($remote)) { //Supress error and write our own
$handle = fopen($local, 'w');
if (fwrite($handle, $data)) {
fclose($handle);
return true;
} else {
fclose($handle);
echo 'Local file '.$local.' could not be written. Check the permissions.';
return false;
}
} else {
echo 'Remote file '.$remote.' could not be found. Some servers reject request without a browser type.';
return false;
}
}
Which is quite simply:
Code: Select all
$data = file_get_contents($remote_file);
$handle = fopen($local_file, 'w');
fwrite($handle, $data);
fclose($handle);
With a bit more error checking. Same thing anyway... just a bit easier

Posted: Sun Jun 26, 2005 7:51 am
by is_blank
Thanks, as well. Very nice. It's helpful to see all this stuff strung together!
