2011-05-30 5 views
5

Comment utiliser Curl pour télécharger un fichier en PHP si les en-têtes sont définis sur true? Puis-je également obtenir le nom de fichier et l'extension du fichier?Comment télécharger un fichier en utilisant curl en php?

Exemple Code PHP:

curl_setopt ($ch, CURLOPT_HEADER, 1); 
$fp = fopen($strFilePath, 'w'); 
curl_setopt($ch, CURLOPT_FILE, $fp); 
+0

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. –

Répondre

4

Télécharger le fichier ou une page web en utilisant PHP cURL et enregistrez-le fichier

<?php 
/** 
* Initialize the cURL session 
*/ 
$ch = curl_init(); 
/** 
* Set the URL of the page or file to download. 
*/ 
curl_setopt($ch, CURLOPT_URL, 
'http://news.google.com/news?hl=en&topic=t&output=rss'); 
/** 
* Create a new file 
*/ 
$fp = fopen('rss.xml', 'w'); 
/** 
* Ask cURL to write the contents to a file 
*/ 
curl_setopt($ch, CURLOPT_FILE, $fp); 
/** 
* Execute the cURL session 
*/ 
curl_exec ($ch); 
/** 
* Close cURL session and file 
*/ 
curl_close ($ch); 
fclose($fp); 
?> 
0

Pour obtenir les en-têtes et les données séparément, vous utilisez généralement à la fois un rappel d'en-tête et un rappel de corps. Comme dans cet exemple:

Pour obtenir le nom de fichier à partir des en-têtes, vous devez rechercher un en-tête Content-Disposition: et extraire le nom de fichier à partir de là (si présent) ou simplement utiliser la partie nom du fichier URL ou similaire Votre choix.

2

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()); 
?> 
1

Je crois que vous avez trouvé votre réponse maintenant. Cependant, j'aimerais partager mon script qui fonctionne bien en envoyant une requête json à un serveur qui retourne le fichier en binaire, puis le télécharge à la volée. L'enregistrement n'est pas nécessaire. J'espère que cela aide!

REMARQUE: Vous pouvez éviter de convertir les données de publication en json.

<?php 

// Username or E-mail 
$login = 'username'; 
// Password 
$password = 'password'; 
// API Request 
$url = 'https://example.com/api'; 
// POST data 
$data = array('someTask', 24); 
// Convert POST data to json 
$data_string = json_encode($data); 
// initialize cURL 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL,$url); 
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 
curl_setopt($ch, CURLOPT_USERPWD, "$login:$password"); 
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); 
curl_setopt($ch, CURLOPT_HEADER, 1); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

// Execute cURL and store the response in a variable 
$file = curl_exec($ch); 

// Get the Header Size 
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 
// Get the Header from response 
$header = substr($file, 0, $header_size); 
// Get the Body from response 
$body = substr($file, $header_size); 
// Explode Header rows into an array 
$header_items = explode("\n", $header); 
// Close cURL handler 
curl_close($ch); 

// define new variable for the File name 
$file_name = null; 

// find the filname in the headers. 
if(!preg_match('/filename="(.*?)"/', $header, $matches)){ 
    // If filename not found do something... 
    echo "Unable to find filename.<br>Please check the Response Headers or Header parsing!"; 
    exit(); 
} else { 
    // If filename was found assign the name to the variable above 
    $file_name = $matches[1]; 
} 
// Check header response, if HTTP response is not 200, then display the error. 
if(!preg_match('/200/', $header_items[0])){ 
    echo '<pre>'.print_r($header_items[0], true).'</pre>'; 
    exit(); 
} else { 
    // Check header response, if HTTP response is 200, then proceed further. 

    // Set the header for PHP to tell it, we would like to download a file 
    header('Content-Description: File Transfer'); 
    header('Content-Type: application/octet-stream'); 
    header('Content-Transfer-Encoding: binary'); 
    header('Expires: 0'); 
    header('Cache-Control: must-revalidate'); 
    header('Pragma: public'); 
    header('Content-Disposition: attachment; filename='.$file_name); 

    // Echo out the file, which then should trigger the download 
    echo $file; 
    exit; 
} 

?> 
Questions connexes