2010-01-15 4 views

Répondre

10
<?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); 

J'ai d'abord essayé d'utiliser php://memory au lieu de /tmp/headers, parce que l'utilisation des fichiers temporaires pour ce genre de chose est bâclée, mais pour une raison quelconque je ne pouvais pas obtenir ce travail. Mais au moins vous avez l'idée ...

Alternativement, vous pouvez utiliser CURLOPT_HEADERFUNCTION

0

Émettez une requête HEAD, faites correspondre le nom de fichier (avec des expressions régulières), puis téléchargez le fichier.

+0

L'émission de deux demandes est inutile. Et il n'y a aucune garantie que la cible supporte réellement HEAD. –

3

Heres une solution sans boucle, mais url_fopen doit être activé pour cela.

$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); 

MISE À JOUR: noms de fichiers dans Content-Disposition peut avoir des espaces (dans ce cas, ils sont écrits entre guillemets simples ou doubles). J'ai résolu ce cas avec un deuxième bloc preg_match.

Questions connexes