In my project, I need to download a file, and I need to use PHP.
All the results from Google were eventually not very helpful.
After combining code from 2 results, I ended up attempting:
function downloadFile($url, $filename) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$data = curl_exec($ch);
curl_close($ch);
header('Content-Description: File Transfer');
header('Content-Type: audio/*');
header("Content-Disposition: attachment; filename=\"$filename\"");
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($data));
readfile($data);
}
The result is an audio file, weighs 10KB (should be 3.58MB).
This code isn't the same as the code in the question that was suggested as a duplicate - here there's a section of curl functions and headers, while the question's answer only has a bunch of headers.
When opened the file with VLC - the following error appears:
Also, I tried using:
file_put_contents($filename, file_get_contents($url));
This one results in downloading the file to the path in which the PHP file is located at - which is not what I want - I need the file to be downloaded to the Downloads folder.
So now I'm basically lost.
What's the appropriate way to download files?
Thanks!
I successfully did it, thanks to Google and a lot of experiments.
The final code:
function downloadFile($url, $filename) {
$cURL = curl_init($url);
curl_setopt_array($cURL, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FILE => fopen("Downloads/$filename", "w+"),
CURLOPT_USERAGENT => $_SERVER["HTTP_USER_AGENT"]
]);
$data = curl_exec($cURL);
curl_close($cURL);
header("Content-Disposition: attachment; filename=\"$filename\"");
echo $data;
}
Related
I've face weird problem below url when I copy and paste it into download manager, it works fine. But I am going to stream it in direct link via PHP then get an 400 error. However when I use the link into different upload center site (uploadboy.com) to test if the link works fine or not, it was working fine on the uploader.
I coded a script that I attach to affix. And try many different way to download it but still face error 400!
What action do I have taken to fix the problem?
I test to see if the script works urlencode and urldecode function on whole parts of url and on query string of url. in these 4 different ways no success to download. However I attached my script in one of the way I tested.
I notice you again. the link working fine and it's not limited to IP Address. However Download Manager that I test to download the url have same IP address with php webserver.
Sample of URL:
http://r5---sn-p5qlsnsk.googlevideo.com/videoplayback?ipbits=0&mm=31&fexp=9407724,9408142,9408592,9408705,9408710,9408982,9412517,9412776,9413317,9413355,945137,948124,952612,952637,952640,952642&id=o-ACIY_VMiJqYl9lskpYea7F_6tP6DNv6WlJattCarpNST&signature=0DF7579F401F8BB481A4511F96ECD95C52FB618B.29AA2A450464D709E3FC3974759459A1EB7066E9&nh=IgpwcjAzLmlhZDA3KgkxMjcuMC4wLjE&key=yt5&mt=1432113172&ip=198.50.235.216&upn=aR3Slhiml7g&expire=1432134981&sparams=dur,id,ip,ipbits,itag,mime,mm,ms,mv,nh,pl,source,upn,expire&mime=video/3gpp&sver=3&pl=23&source=youtube&mv=u&dur=87.817&itag=17&ms=au&signature= '&title='Youtube-API-V3-Drag--Drop-PlayList--Download-videos--Search-Keyword'
Sample of Code to stream:
$url = $_POST['url'];
$referrer = $_POST['referrer'];
if(strstr($url,'googlevideo.com')){
$url_parts = parse_url($url);
$query = $url_parts['query'];
$query_parts = parse_str($query,$queries);
foreach ($queries AS $key=>$value){
$post_url .= $key.'='.urlencode($value).'&';
}
$post_url = rtrim($post_url, '&');
$url2 = 'http://r1---sn-u2oxu-f5f6.googlevideo.com/videoplayback?'.$post_url;
die($url.'<br><br>'.$url2);
$filename = preg_replace('/[^a-zA-Z0-9-_\.]/','', $title).'.'.getExtension($mime);
// $head = array_change_key_case(get_headers($url, TRUE));
// $filesize = $head['content-length'];
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private',false);
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
header('Content-Transfer-Encoding: binary');
// header('Content-Length: '.$filesize); // provide file size
header('Connection: close');
// echo getUrl($url,$_SERVER['HTTP_USER_AGENT'],$referrer);
$file = fopen(str_replace('&','&',$url), 'rb');
while (($content = fread($file, 20480)) !== false) { // Read in 2048-byte chunks
echo $content; // or output it somehow else.
flush(); // force output so far
}
fclose($file);
exit();
}
Update1:
I already test below curl function:
function getUrl($url,$agent='',$referrer='',$proxy=''){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
if(!empty($agent)){
curl_setopt ($ch, CURLOPT_USERAGENT,$agent);
}
curl_setopt ($ch, CURLOPT_TIMEOUT, 60);
if(!empty($referrer)){
curl_setopt ($ch, CURLOPT_REFERER, $referrer);
}
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,false);
$output=curl_exec($ch);
curl_close($ch);
return $output;
}
The 400 error comes from a typo in your url: remove the space character in this part: &signature= '&title='.
Your curl function is ok, but it doesn't work with your url. I don't know why not, but it works with an url like this: https://youtu.be/LxBk5f6mr-A.
Perhaps you can use the tool mentioned in this post:
grabbing youtube video URL from curl or get_video_info
I want to get a video file from another server, and open it on my website in flowplayer.
I did this :
$ch = curl_init('http://example.com/file.flv');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
header("Content-Type: video/flv");
header("Content-Disposition: attachment; filename=video.flv;" );
header("Content-Length: ".$size);
readfile($result);
But there is a problem with the size of file, it always shows wrong size of file (too small)
I have to use a cURL, because only my server IP can get a video from video server.
Thanks for help
readfile() is used to reads a file and write it to the output, use echo instead of, otherwise, use strlen to get content length, try the code below:
$ch = curl_init('http://example.com/file.flv');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$size = strlen($result);
header("Content-Type: video/flv");
header("Content-Disposition: attachment; filename=video.flv;" );
header("Content-Length: ".$size);
echo $result;
I'm using CURL to fetch an image file from our server. After checking the browser's developer tools, it says that the returned type is 'html' instead of 'image'.
Here's the response:
/f/gc.php?f=http://www.norbert.com/get/image/BTS-005-00.jpg
GET 200 text/html 484.42 KB 1.68 s <img>
Here's the CURL script:
$ch = curl_init();
$strUrl = $strFile;
curl_setopt($ch, CURLOPT_URL, $strUrl);
curl_setopt($ch, CURLOPT_USERAGENT, "MozillaXYZ/1.0");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
$output = curl_exec($ch);
curl_close($ch);
return $output;
Any additional specific code that I could add in my CURL script?
Thanks!
Your PHP script is doing a cURL and returning the output without specific header of image.
So, by default, the browser will retrieve the data as HTML content.
Try to add a more specific header before returning the output.
Try
header('Content-Type: image/jpg');
to specify to the browser the type of content your script is actually sending.
If you want the user to be able to download as file, you can also add the header:
header('Content-Disposition: attachment; filename="' . $fileName . '";');
If you are sending binary content, you could add:
header("Content-Transfer-Encoding: binary");
Whats the best what to enable a user to click a download button that then automatically gets a image file and then downloads it to their generic downloads folder or prompts them to save it?
i have tried the following but with no success:
$file = $art[0]['location']; // this is the full url to image http://....image.jpg
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch,CURLOPT_URL, $file);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$file_content = curl_exec($ch);
curl_close($ch);
ect or am i going about this all wrong (probably)
thanks
Before you echo the data:
header('Content-Disposition: attachment; filename=save_as_name.jpg');
Then
echo file_get_contents("http://...");
header('Content-Disposition: attachment; filename="exmaple.jpg"');
header('Content-Type: application/octet-stream'); // (or a MIME type like "image/jpeg")
echo $file_content;
I had a code that worked, here:
if (isset($_GET['file']) && isset($_GET['name']))
{
$file = base64_decode($_REQUEST['file']);
$ch = curl_init($file);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$data = curl_exec($ch);
curl_close($ch);
if (preg_match('/Content-Length: (\d+)/', $data, $matches))
{
// Contains file size in bytes
$contentLength = (int)$matches[1];
}
header("Content-type: application/x-file-to-save");
header("Content-Disposition: attachment; filename=".$_REQUEST['name']);
header('Content-Length: ' . $contentLength);
header('Content-Transfer-Encoding: binary');
#readfile($file);
}
And than I changed my server to a differenf host providor, and the code stoped working. When I download from chrome it just keeps loading and loading,
but when I download from a download manager like IDM than it gets the correct name and size, but when I press start it makes an error that says something about not supporting resuming or something...
Again, the code worked when I used a different providor.
It might be errors which are outputted before readfile() use ob_clean();
flush(); to remove any output before readfile