Using the default filename (content_disposition) when downloading with CURL Using the default filename (content_disposition) when downloading with CURL curl curl

Using the default filename (content_disposition) when downloading with CURL


<?php$targetPath = '/tmp/';$filename = $targetPath . 'tmpfile';$headerBuff = fopen('/tmp/headers', 'w+');$fileTarget = fopen($filename, 'w');$ch = curl_init('http://www.example.com/');curl_setopt($ch, CURLOPT_WRITEHEADER, $headerBuff);curl_setopt($ch, CURLOPT_FILE, $fileTarget);curl_exec($ch);if(!curl_errno($ch)) {  rewind($headerBuff);  $headers = stream_get_contents($headerBuff);  if(preg_match('/Content-Disposition: .*filename=([^ ]+)/', $headers, $matches)) {    rename($filename, $targetPath . $matches[1]);  }}curl_close($ch);

I initially tried to use php://memory instead of /tmp/headers, 'cause using temp files for this sort of thing is sloppy, but for some reason I couldn't get that working. But at least you get the idea...

Alternately, you could use CURLOPT_HEADERFUNCTION


Heres a solution without curl but url_fopen has to be enabled for this.

$response_headers = get_headers($url,1); // first take filename from url$filename = basename($url);   // if Content-Disposition is present and file name is found use thisif(isset($response_headers["Content-Disposition"])){  // this catches filenames between Quotes  if(preg_match('/.*filename=[\'\"]([^\'\"]+)/', $response_headers["Content-Disposition"], $matches))  { $filename = $matches[1]; }  // if filename is not quoted, we take all until the next space  else if(preg_match("/.*filename=([^ ]+)/", $response_headers["Content-Disposition"], $matches))  { $filename = $matches[1]; }}// if no Content-Disposition is found use the filename from url// before using the filename remove all unwanted chars wich are not on a-z e.g. (I the most chars which can be used in filenames, if you like to renove more signs remove them from the 1. parameter in preg_replace$filename = preg_replace("/[^a-zA-Z0-9_#\(\)\[\]\.+-=]/", "",$filename);// at last download / copy the contentcopy($url, $filename);

UPDATE: Filenames in Content-Disposition can have spaces (in that case they are written in single or double quotes). I solved this case with a second preg_match block.


Issue an HEAD request, match the filename (with regular expressions) and then download the file.