I have a code in cURL that should copy an image from a URL to my server:
$curl = curl_init( $url );
$file = fopen( $imageURL , 'wb' );
curl_setopt( $curl , CURLOPT_FILE , $file );
curl_setopt( $curl , CURLOPT_HEADER , true );
curl_setopt( $curl , CURLOPT_FOLLOWLOCATION , true );
curl_exec( $curl );
curl_close( $curl );
fclose( $file );
it doesn't work correctly but file_put_contents() does. Is there something wrong with my cURL code?
There are multiple solutions, cURL probably isn't the best.
$remote_img = 'http://www.somwhere.com/images/image.jpg';
$img = imagecreatefromjpeg($remote_img);
$path = 'images/';
imagejpeg($img, $path);
Would work nicely, but if you are set on cURL, try this:
$ch = curl_init ($img);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$rawdata=curl_exec($ch);
curl_close ($ch);
if(file_exists($fullpath)){
unlink($fullpath);
}
$fp = fopen($fullpath,'x');
fwrite($fp, $rawdata);
fclose($fp);
That should work as well.
Best of luck!
Dont set CURLOPT_HEADER to true. This will include the header in the output. So your image file will contain response header + image data. Remove that line or set it false.
Related
I am trying to download a pronunciation file (approx. 8kb) to server using a server-side PHP. Taking cue from a number of threads discussing this issue, I tried the following:
$numwrd = str_word_count($wrd);
if($numwrd == 1){
$html = file_get_html("http://www.dictionaryapi.com/api/v1/references/spanish/xml/" . rawurlencode($wrd) . "?key=" . rawurlencode('6d4d41f9-c28f-4544-9bb3-1b4708d1a4d1'));
$sn = $html->find('sound');
if($sn[0] != ""){
$foldername = findsub($sn[0]->plaintext);
$filename = explode(".", $sn[0], 2)[0];
$audiofn = $foldername . $filename . '.mp3';
$soundurl = 'http://media.merriam-webster.com/audio/prons/es/me/mp3/' . $foldername . '/' . $filename . '.mp3';
$path = 'amit.mp3';
$headers = getHeaders($soundurl);
if ($headers['http_code'] === 200 and $headers['download_content_length'] < 1024*1024) {
if (download($url, $path)){
return $audiofn . " " . $soundurl;
}
}
}
else { return "not found"; }
}
else { return "not found"; }
function getHeaders($url)
{
$ch = curl_init($url);
curl_setopt( $ch, CURLOPT_NOBODY, true );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
curl_setopt( $ch, CURLOPT_HEADER, false );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $ch, CURLOPT_MAXREDIRS, 3 );
curl_exec( $ch );
$headers = curl_getinfo( $ch );
curl_close( $ch );
return $headers;
}
function download($url, $path)
{
# open file to write
$fp = fopen ($path, 'w+');
# start curl
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
# set return transfer to false
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
# increase timeout to download big file
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10 );
# write data to local file
curl_setopt( $ch, CURLOPT_FILE, $fp );
# execute curl
curl_exec( $ch );
# close curl
curl_close( $ch );
# close local file
fclose( $fp );
if (filesize($path) > 0) return true;
}
This didn't work so I tried again with file_get_contents. This method however only creates the file but with zero bytes. The values in $foldername, $filename, $audiofn, and $soundurl are evaluating correctly and all these variables have been tested. I can manually download the file by browsing to the URL, right clicking in the browser, and clicking download file as.... What could be wrecking my PHP?
P.S.: I just tried a modified function using cURLand this failed too:
function down($url, $target){//feeding it $soundurl and $path values
set_time_limit(0);
$file = fopen(dirname(__FILE__) . $target, 'w+');
$curl = curl_init($url);
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_BINARYTRANSFER => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FILE => $file,
CURLOPT_TIMEOUT => 50,
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
]);
$response = curl_exec($curl);
if($response === false) {
throw new \Exception('Curl error: ' . curl_error($curl));
}
$response;
}
Finally got it to work! This is what fixed it (line 7):
$filename = explode(".", $sn[0]->plaintext, 2)[0];
The reason I had to add the ->plaintext attribute is because without it, the value being returned to $filename was an xml tag instead of the text inside of that tag. Since the following line of code takes this value as input, this was corrupting the URL being called for download:
$soundurl = 'http://media.merriam-webster.com/audio/prons/es/me/mp3/' . $foldername . '/' . $filename . '.mp3';
Now the file downloads successfully because the URL is being formed correctly.
I want to display the size of youtube video size on the direct link. I have a link to an mp4 format file that is 98 MB in size. I want to display the size when you browse this link your will get file.
Direct url link:
$url ='https://r4---sn-a8au-p5qs.googlevideo.com/videoplayback?signature=9216B94F5EA16F023DE3D34C6881F8AFA20E1EBA.4B56920C4B2BAB848AC847E0EB4C1E01FB01685C&itag=22&ratebypass=yes&expire=1424904527&id=o-AA8OyXA6gxAGHzkwqf94rIO0LTrhD8iHuUc9lMI9ED76&pl=46&fexp=905657%2C907263%2C916942%2C923382%2C927622%2C934601%2C934954%2C9406984%2C943917%2C947225%2C947240%2C947601%2C948124%2C951703%2C952302%2C952605%2C952612%2C952901%2C955301%2C957201%2C959701&mm=31&ipbits=0&dur=1366.192&mt=1424882845&ms=au&key=yt5&upn=SIiUMnjm5o0&source=youtube&sparams=dur%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Cmm%2Cms%2Cmv%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cupn%2Cexpire&mv=m&initcwndbps=1567500&ip=2001%3A4802%3A7805%3A101%3Abe76%3A4eff%3Afe20%3A31e4&sver=3&requiressl=yes&title=PHP%3A+Create+Your+Own+MVC+%28Part+1%29';
php curl code I am using to get code
function retrieve_remote_file_size($url){
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_NOBODY, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$data = curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
return $size;
}
It is giving me 1419. How do I get the correct file size?
getID3 supports video formats. See: http://getid3.sourceforge.net/
$getID3 = new getID3;
$file = $getID3->analyze($filename);
echo("Filesize: ".$file['filesize']." bytes<br />");
Note: You must include the getID3 classes before this will work! See the above link.
If you have the ability to modify the PHP installation on your server, a PHP extension for this purpose is ffmpeg-php. See: http://ffmpeg-php.sourceforge.net/
edit:
Found something about this here:
Here's the best way (that I've found) to get the size of a remote file. Note that HEAD requests don't get the actual body of the request, they just retrieve the headers. So making a HEAD request to a resource that is 100MB will take the same amount of time as a HEAD request to a resource that is 1KB.
$curl = curl_init( $url );
// Issue a HEAD request and follow any redirects.
curl_setopt( $curl, CURLOPT_NOBODY, true );
curl_setopt( $curl, CURLOPT_HEADER, true );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $curl, CURLOPT_USERAGENT, get_user_agent_string() );
$data = curl_exec( $curl );
curl_close( $curl );
if( $data ) {
$content_length = "unknown";
$status = "unknown";
if( preg_match( "/^HTTP\/1\.[01] (\d\d\d)/", $data, $matches ) ) {
$status = (int)$matches[1];
}
if( preg_match( "/Content-Length: (\d+)/", $data, $matches ) ) {
$content_length = (int)$matches[1];
}
// http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
if( $status == 200 || ($status > 300 && $status <= 308) ) {
$result = $content_length;
}
}
return $result;
}
?>
Usage:
$file_size = curl_get_file_size( "http://stackoverflow.com/questions/2602612/php-remote-file-size-without-downloading-file" );
The 1491 bytes you get is the length of the redirect. Add the following curl option:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, True);
According to the documentation it should be true by default, but it wasn't for me.
help me to fix this problem
I want to download Facebook user image profile using PHP 5.3.27
I use this code, the image is downloaded but size 0 bytes and cannot be open.
first code:
function DownloadImage($url, $dest){
$curl = curl_init($url);
$fp = fopen($dest, 'wb');
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_exec($curl);
curl_close($curl);
fclose($fp);
}
try{
$social_id='1234';
DownloadImage('http://graph.facebook.com/'.$social_id.'/picture', '../user_image/normal/'.$social_id.'.jpg');
DownloadImage('http://graph.facebook.com/'.$social_id.'/picture?width=141&height=141', '../user_image/bigger/'.$social_id.'.jpg');
}
catch(Exception $errr){
echo $errr;
}
and this is the second code..
with the same result (0 bytes of size and cannot be open)
$url = 'http://graph.facebook.com/1234/picture';
$img = '../user_image/bigger/1234.jpg';
file_put_contents($img, file_get_contents($url));
As I see
http://graph.facebook.com/1234/picture
do redirect to:
https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/t1.0-1/c47.7.85.85/s50x50/417599_10100236041078581_1583446385_a.jpg
Try to add:
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
TRUE to follow any "Location: " header that the server sends as part of the HTTP header (note this is recursive, PHP will follow as many "Location: " headers that it is sent, unless CURLOPT_MAXREDIRS is set).
So your code may looks like:
function DownloadImage($url, $dest){
$curl = curl_init($url);
$fp = fopen($dest, 'wb');
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_exec($curl);
curl_close($curl);
fclose($fp);
}
try{
$social_id='1234';
DownloadImage('http://graph.facebook.com/'.$social_id.'/picture', '../user_image/normal/'.$social_id.'.jpg');
DownloadImage('http://graph.facebook.com/'.$social_id.'/picture?width=141&height=141', '../user_image/bigger/'.$social_id.'.jpg');
}
catch(Exception $errr){
echo $errr;
}
I want to get details from a url using CURL its works fine for normal character URL. But one of amy URL includes special character like 'ó'.
My URL sample is as follows:
http://www.abc.com/aóvek-xyz-pqr/1/8/
My php code is :
$ch = curl_init($my_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
$content = curl_exec($ch);
Try with the following (taken from urlencode only the directory and file names of a URL):
$encoded_url = preg_replace_callback('#://([^/]+)/([^?]+)#', function ($match) {
return '://' . $match[1] . '/' . join('/', array_map('rawurlencode', explode('/', $match[2])));
}, $my_url);
$ch = curl_init($encoded_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
$content = curl_exec($ch);
URL's in http can only be constructed with a specific set of characters. For every other you need to percent encode them.
http://en.wikipedia.org/wiki/Percent-encoding
In PHP you can use urlencode
http://php.net/manual/en/function.urlencode.php
Your code should look like this
$ch = curl_init(urlencode($my_url));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
$content = curl_exec($ch);
try this
function get_web_page( $url )
{
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
);
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
curl_close( $ch );
return $content;
}
echo get_web_page("http://en.wikipedia.org/wiki/ó");
I really, really need help as to how to solve this issue I'm having:
Using script:
<?php
$curl = curl_init();
$fp = fopen("somefile.zip", "w");
curl_setopt ($curl, CURLOPT_URL, "http://website.com/test.zip");
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_exec ($curl);
curl_close ($curl);
I have asked before, and no-one seems to have a solution as to how I solve this... If someone can even tell me why it's happening ie. is it file size, binary transfer etc. I can work with that!
The file ZIP file downloads and creates somefile.zip but the XML file within is partially corrupt.
Sample:
K#Teº22)dVTð¼ÜvØ
rÏ*HIê±dE*¬òPÜÊâR}ÝbJÉÂX:Î#z|Eª2Ér tk2UÄOK¼É,·,Ûs¦ê1Z°VÝk6Ù«ËGÝw©5Æ]ÛQcq¥¼½ØïÒÐ]êÈy¨ð¶Çùûü]ÛßþW¤ùâÝÀw|~§ïúÁ¸ÛHBq®*YtrÛÕiî$ /ñ¥n?è¶;_ò
É¡ä ç&ýOr óß)yÿ¤$+`~TÙAófHU ¢SÝvW¶¦xA5Å׶Ãrå<8^ÐË4w qz Ø«<Ñ"*ººÝ?èO^;ÃQûÉOÏÀ¾?ìw|Õ±¥©3w©Ýr£ ÃÊÀ ¿^Á^UÛLß_ôÜÎh4îÖWcíF^8¾ö÷ؼ¾¿`âX3Ûú^{ À<.Æ¡(±1f¢.¸®k/ìÝeÓçê'PAnÓõ¸K`TeQ÷b|'¥Ñ)1ÓãnsÞèàÎZ|ê*+kuw×cªëÇ:§$¤ã¸Î1ü±Úh6ÕÀQ¦©D4Âp4b{Èo¾
,4"R
Can you set CURLOPT_HEADER to 0 and try again?
Edit:
Or try this:
$url = 'http://website.com/test.zip';
$path = 'somefile.zip';
$ch = curl_init($url);
if($ch === false)
{
die('Failed to create curl handle');
}
$fp = fopen($path, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);