Voici un exemple complet qui utilise une classe. L'analyse de l'en-tête est plus élaborée que possible, parce que je posais la base pour un stockage d'en-tête hiérarchique complet. Je viens de remarquer que init() devrait réinitialiser beaucoup plus de variables s'il veut être possible de réutiliser l'instance pour plus d'URL, mais cela devrait au moins vous donner une base de comment télécharger un fichier à un nom de fichier envoyé par le serveur.
<?php
/*
* vim: ts=4 sw=4 fdm=marker noet tw=78
*/
class curlDownloader
{
private $remoteFileName = NULL;
private $ch = NULL;
private $headers = array();
private $response = NULL;
private $fp = NULL;
private $debug = FALSE;
private $fileSize = 0;
const DEFAULT_FNAME = 'remote.out';
public function __construct($url)
{
$this->init($url);
}
public function toggleDebug()
{
$this->debug = !$this->debug;
}
public function init($url)
{
if(!$url)
throw new InvalidArgumentException("Need a URL");
$this->ch = curl_init();
curl_setopt($this->ch, CURLOPT_URL, $url);
curl_setopt($this->ch, CURLOPT_HEADERFUNCTION,
array($this, 'headerCallback'));
curl_setopt($this->ch, CURLOPT_WRITEFUNCTION,
array($this, 'bodyCallback'));
}
public function headerCallback($ch, $string)
{
$len = strlen($string);
if(!strstr($string, ':'))
{
$this->response = trim($string);
return $len;
}
list($name, $value) = explode(':', $string, 2);
if(strcasecmp($name, 'Content-Disposition') == 0)
{
$parts = explode(';', $value);
if(count($parts) > 1)
{
foreach($parts AS $crumb)
{
if(strstr($crumb, '='))
{
list($pname, $pval) = explode('=', $crumb);
$pname = trim($pname);
if(strcasecmp($pname, 'filename') == 0)
{
// Using basename to prevent path injection
// in malicious headers.
$this->remoteFileName = basename(
$this->unquote(trim($pval)));
$this->fp = fopen($this->remoteFileName, 'wb');
}
}
}
}
}
$this->headers[$name] = trim($value);
return $len;
}
public function bodyCallback($ch, $string)
{
if(!$this->fp)
{
trigger_error("No remote filename received, trying default",
E_USER_WARNING);
$this->remoteFileName = self::DEFAULT_FNAME;
$this->fp = fopen($this->remoteFileName, 'wb');
if(!$this->fp)
throw new RuntimeException("Can't open default filename");
}
$len = fwrite($this->fp, $string);
$this->fileSize += $len;
return $len;
}
public function download()
{
$retval = curl_exec($this->ch);
if($this->debug)
var_dump($this->headers);
fclose($this->fp);
curl_close($this->ch);
return $this->fileSize;
}
public function getFileName() { return $this->remoteFileName; }
private function unquote($string)
{
return str_replace(array("'", '"'), '', $string);
}
}
$dl = new curlDownloader(
'https://dl.example.org/torrent/cool-movie/4358-hash/download.torrent'
);
$size = $dl->download();
printf("Downloaded %u bytes to %s\n", $size, $dl->getFileName());
?>
Ces réponses ont-elles fonctionné pour vous? Si oui alors s'il vous plaît le plus utile comme correct pour l'aide des autres. –