PHP: Ottenere il nome di un file dagli headers
Come ottenere il nome di un file, a cui facciamo riferimento con un URL, dagli headers.
Scenario
Il PHP è un linguaggio molto versatile e può essere utilizzato per gestire processi automatici, soprattutto quando questi coinvolgono il protocollo HTTP. Un esempio è lo scaricamento di un file da un URL. E’ sempre più difficile trovare URL che puntano direttamente al file, molto più spesso puntano a degli script che hanno il compito di gestire il download. Questi script, in genere, agiscono facendo un redirect verso il mirror più vicino o prelevando informazioni per effettuare delle statistiche.
In questi casi non è sempre possibile ottenere il nome del file dall’URL, possiamo però ottenerlo grazie all’analisi degli headers.
Analisi
Utilizzeremo una funzione che richiede come unico parametro la stringa contenente l’URL. La funzione dovrà ottenete gli headers, verificare se esiste l’header “Location”, ovvero un reindirizzamento verso un altro URL, nel qual caso dovrà richiamare se stessa(1) passando come parametro il nuovo URL. Se non c’è nessun reindirizzamento dovrà cercare l’header “Content-Disposition” ed estrarre il nome del file. Qualora non fossero presenti informazioni sul nome del file negli header, questo verrà determinato utilizzando l’URL. Dopo aver effettuato una normalizzazione della stringa trovata, la funzione dovrà restituire il risultato, se valido, altrimenti restituirà “False”
Codice
function url2filename($url) {
$headers = get_headers($url, 1);
if (!empty($headers['Location'])) {
return url2filename($headers['Location']);
} $filename = basename($url);
foreach (array('Content-Disposition', 'content-disposition') as $contentDisposition) {
if (isset($headers[$contentDisposition])) {
foreach (array('[\'\"]([^\'\"]+)', '(\.+);', '(\.+)') as $pattern) {
if (preg_match("/.*filename={$pattern}/", $headers[$contentDisposition], $matches)) {
$filename = $matches[1];
break 2;
}
}
}
} $filename = preg_replace('/[^a-zA-Z0-9\._-\s]/', '', urldecode($filename));
return (!empty($filename) ? $filename : false );
}
Esempio di utilizzo
$url = 'http://it1.php.net/get/php-5.6.0.tar.xz/from/this/mirror';
$path = dirname(__FILE__);
$filename = url2filename($url);
if ( !empty ( $filename ) ) {
copy($url, $path. '/' . $filename);
}
Note
1) Una funzione che richiama se stessa è detta “ricorsiva”.
Wow….complimenti per questo dettagliatissimo articolo…!!!!! GRAZIE!!!