Использование имени файла по умолчанию (content_disposition) при загрузке с CURL - PullRequest
3 голосов
/ 15 января 2010

Я пытаюсь загрузить некоторые файлы с помощью PHP & CURL, но я не вижу простого способа использовать предложенное по умолчанию имя файла (которое находится в заголовке ответа HTTP как

Содержание-Диспозиция: вложение; имя файла = foo.png

). Есть ли более простой способ, чем получить полный заголовок, разобрать имя файла и переименовать?

Ответы [ 3 ]

11 голосов
/ 15 января 2010
<?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: // memory вместо /tmp/headers, потому что использование временных файлов для такого рода вещей небрежно, но по какой-то причине я не смог получитьчто работает.Но, по крайней мере, вы поняли идею ...

Альтернативно, вы можете использовать CURLOPT_HEADERFUNCTION

4 голосов
/ 25 мая 2014

Вот решение без скручивания, но для этого должен быть включен 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 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 content
copy($url, $filename);

ОБНОВЛЕНИЕ: Имена файлов в Content-Disposition могут иметь пробелы (в этом случае они пишутся в одинарных или двойных кавычках). Я решил этот случай со вторым блоком preg_match.

0 голосов
/ 15 января 2010

Выполните запрос HEAD, сопоставьте имя файла (с регулярными выражениями) и затем загрузите файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...