2009-09-09 5 views
1

J'ai un script PHP qui est censé contenir une URL et rechercher une base de données pour une version en cache de l'URL. S'il le trouve, il imprime la version mise en cache à l'utilisateur, sinon il la télécharge en utilisant cURL et l'envoie à l'utilisateur. À l'heure actuelle, le script de téléchargement ressemble à quelque chose comme ceci:PHP Curl: lire de manière incrémentielle

// create a new cURL resource 
$ch = curl_init(); 
// set URL and other appropriate options 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_HEADER, 0); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 
// grab URL and pass it to the browser 
$data = curl_exec($ch); 
$mimetype = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); 
// close cURL resource, and free up system resources 
curl_close($ch); 

mysql_query("INSERT INTO `cache_files` (`key`, `original_url`, `file_data`, `mime_type`) VALUES (". 
    "'" . mysql_real_escape_string($key) . "', " . 
    "'" . mysql_real_escape_string($url) . "', " . 
    "'" . mysql_real_escape_string($data) . "', " . 
    "'" . mysql_real_escape_string($mimetype) . "')" 
); 

if (isset($_GET["no_output"])) die; 

header ("Content-Type: " . $mimetype); 
header ('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + 157680000), true); 
header ('Last-Modified: '.gmdate('D, d M Y H:i:s \G\M\T'), true); 
header ('Cache-Control: public; max-age=157680000'); 
header ('Pragma: '); 
print $data; 

Cela fonctionne actuellement bien, cependant, de gros fichiers ne sont pas envoyés à l'utilisateur final jusqu'à ce qu'ils soient téléchargés 100%, ce qui provoque un rendu supplémentaire ne doit être déclenchée. Je veux savoir s'il existe un moyen pour cURL de transmettre les données à l'utilisateur lors du téléchargement, mais aussi de disposer les données dans une chaîne pour la consommation de script.

Répondre

1

Vous pouvez utiliser le rappel CURLOPT_WRITEFUNCTION pour vous connecter au traitement des données de réponse de cURL. exemple (via http://www.php.net/manual/en/function.curl-setopt.php#26239):

<?php 

function myPoorProgressFunc($ch, $str) { 
    global $fd; 

    $len = fwrite($fd, $str); 
    print('#'); 
    return $len; 
} 

curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'myPoorProgressFunc'); 

au lieu d'écrire les données dans un fichier et la sortie « # », vous pouvez écrire les données dans le navigateur et l'enregistrer dans la chaîne. Cependant, je serais prudent avec ce dernier pour les fichiers volumineux.

2

Voici une classe brute et incomplète (mais fonctionnelle) pour tester l'utilisation de l'option CURLOPT_WRITEFUNCTION. Selon le libcurl documentation, la fonction donnée pour cette option "est appelée par libcurl dès qu'il y a des données qui doivent être sauvegardées." Donc le contenu reçu par curl devrait être passé au serveur tel qu'il est reçu. Quand il est effectivement affiché dépendrait, bien sûr, sur le serveur et le navigateur.

$url = 'http://stackoverflow.com/'; 
$curl_test = new CurlCallbackTest($url); 
file_put_contents('some.file', $curl_test->content); 

class CurlCallbackTest 
{ 
    public $content = ''; 

    public function __construct($url) 
    { 
     $ch = curl_init($url); 
     curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'showContent')); 
     curl_setopt($ch, CURLOPT_HEADER, false); 
     curl_exec($ch); 
     curl_close($ch); 
    } 

    private function showContent($ch, $data) 
    { 
     $this->setContent($data); 
     echo htmlspecialchars($data); 
     return strlen($data); 
    } 

    private function setContent($data) 
    { 
     $this->content .= $data; 
    } 
} 
Questions connexes