PHP Curl: aşamalı oku

2 Cevap php

Ben bir URL almak ve URL önbelleğe alınmış bir sürümü için bir veritabanı arama gerekiyordu bir PHP komut dosyası var. Onu bulursa, bu, kullanıcıya önbelleğe alınmış sürümünü yazdırır aksi cURL kullanarak indirir ve kullanıcıya echos. Şu anda, indirme komut şöyle:

// 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;

Bu şu anda gayet iyi çalışıyor onlar% 100 artırımlı render tetiklenir değil neden olan, indirilen kadar, ancak, büyük dosyaları son kullanıcıya göndermek değildir. Ben cURL indirilirken kullanıcıya verileri aktarmak, aynı zamanda komut tüketimi için bir dize veri mevcut olabilir ki bir yolu olup olmadığını bilmek istiyorum.

2 Cevap

Eğer kullanabilirsiniz CURLOPT_WRITEFUNCTION callback to hook into cURL's response data handling. example (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');

yerine bir dosyaya veri yazma ve '#' çıktısı, tarayıcıya veri yazmak ve dizede saklayabilirsiniz. Ancak, ben büyük dosyalar için son ile temkinli olacaktır.

İşte CURLOPT_WRITEFUNCTION seçeneği kullanımını test etmek için bir ham ve eksik (ama çalışmıyor) sınıfı bulunuyor. libcurl documentation göre, bu seçenek için verilen fonksiyonu "veri kaydedilir gerektiğini Alınan olduğu kısa sürede libcurl tarafından çağrılır." Yani kıvrılma tarafından alınan içerik alındığı gibi sunucuya geçirilmelidir. Aslında görüntülendiğinde sunucu ve tarayıcı üzerinde, tabii ki, bağımlı olacaktır.

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