Я пытаюсь загрузить некоторые файлы с помощью PHP & CURL, но я не вижу простого способа использовать предложенное по умолчанию имя файла (которое находится в заголовке ответа HTTP как
Content-Disposition: вложение; имя файла = foo.png
). Есть ли более простой способ получить полный заголовок, проанализировать имя файла и переименовать?
<?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);
Первоначально я пытался использовать память php: // вместо /tmp/headers
, потому что использование временных файлов для такого рода вещей неаккуратно, но по какой-то причине я не мог заставить это работать. Но, по крайней мере, вы получаете идею …
Кроме того, вы можете использовать CURLOPT_HEADERFUNCTION
Heres решение без curl, но url_fopen должен быть включен для этого.
$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 this if(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 az eg (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 content copy($url, $filename);
UPDATE: имена файлов в Content-Disposition могут иметь пробелы (в этом случае они записываются в одинарных или двойных кавычках). Я решил этот случай со вторым блоком preg_match.
Выполните запрос HEAD, сопоставьте имя файла (с регулярными выражениями), а затем загрузите файл.