2013-06-30 54 views
3

在PHP中使用捲曲前檢查響應頭,有什麼辦法下載前身體檢查HTTP響應頭? 比方說,我做一個GET請求URI一些,我想抓住的內容只有Content-typetext/html。我知道我可以首先創建一個HEAD請求,然後決定是否使用GET,但是可能只需要一個請求?PHP /曲:下載體

基本上,我找下面的C#代碼的等效:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://some.uri"); 
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
if(response.ContentType.Equals("text/html")) { 
    string body = new StreamReader(response.GetResponseStream()).ReadToEnd(); 
} else { 
    // do nothing 
} 

這可能嗎?

+0

做你試過'CURLOPT_HEADER '和'CURLOPT_NOBODY'選項? – bystwn22

+0

@ bystwn22'CURLOPT_NOBODY'使curl發送一個HEAD請求。我知道它可以使用HEAD +條件GET來完成;我正在尋找的是一種在一個請求中執行此操作的方法。 – zuza

+0

毫米。是啊,明白了,看到我的回答如下,希望如果不將工作:),原諒我,我是一個菜鳥:) – bystwn22

回答

3

是的,我得到了你,你可以在這種情況下使用CURLOPT_WRITEFUNCTION
爲了使事情更快漂亮,我用我所有的項目我自己curl類。
讓我也發佈。
看到我的代碼如下。

<?php 
    require_once("curl.class.php"); 

    /** variable to store response body **/ 
    $response_body = null; 
    /** total size of header in response **/ 
    $header_size = null; 

    /** initialize the curl object **/ 
    $curl = new ipCurl("http://example.com/images/someimage.jpg"); 
    /** set a read callback **/ 
    $curl->setReadCallback("my_read_callback"); 
    /** Include header in response **/ 
    $curl->includeHeader(); 
    /** start curl **/ 
    $curl->createCurl(); 

    if ($curl->getError() !== 0) { 
    /** something went wrong, print the error message, and error code **/ 
    echo $curl->getError().":".$curl->getErrorMessage(); 

    if ($curl->getError() === 23) { 
     // its not an image file (Failed writing body....) 
    } 
    } 
    else { 
    /** Everything fine, lets parse the body from response **/ 
    $response_body = substr($response_body, $header_size); 
    file_put_contents("image.jpg", $response_body); 
    } 

    /** The function for our curl write callback **/ 
    function my_read_callback(&$ch, $data) { 
    global $response_body, $header_size; 
    /** Get the content type **/ 
    $content_type = trim(curl_getinfo($ch, CURLINFO_CONTENT_TYPE)); 
    /** Give it time to get the content-type string from header **/ 
    if (!empty($content_type)) { 
     /** stop executing curl if its not an image **/ 
     if ($content_type !== "image/jpeg") { 
     return false; 
     } 
    } 
    /** size of the header **/ 
    $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 
    /** append resposne body to $response_body **/ 
    $response_body .= $data; 
    /** return current response length **/ 
    return strlen($data); 
    } 
?> 

curl.class.php文件內容

<?php 
class ipCurl { 
    private $ch = null; 
    private $url = null; 

    private $_error = 0; 
    private $_errmsg = null; 
    private $_header = null; 
    private $_webpage = null; 
    private $_status = 0; 

    public function __construct($url = null) { 
    $this->url = $url; 

    if (!function_exists("curl_init")) { 
     throw new Exception("Fatal Error: Module 'Curl' is not installed properly"); 
    } 

    $this->ch = curl_init(); 

     curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); 
     curl_setopt($this->ch, CURLOPT_FRESH_CONNECT, false); 
     curl_setopt($this->ch, CURLOPT_FORBID_REUSE, false); 

    $this->setTimout(40); 
    $this->setConnTimout(30); 
    $this->followLocation(); 
    $this->setMaxRedirects(4); 
    $this->excludeHeader(); 
    $this->includeBody(); 
    $this->verifySSL(); 
    $this->setBinaryTransfer(); 
    $this->setReferer($_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]); 
    $this->setUserAgent(); 

    return $this; 
    } 

    public function __destruct() { 
    curl_close($this->ch); 
    $this->ch = null; 
    } 

    public function setReadCallback($callback = null) { 
    curl_setopt($this->ch, CURLOPT_WRITEFUNCTION, $callback); 
    return $this; 
    } 

    public function setProgressCallback($callback = null, $buffer = 128) { 
    curl_setopt($this->ch, CURLOPT_NOPROGRESS, false); 
    curl_setopt($this->ch, CURLOPT_PROGRESSFUNCTION, $callback); 
    curl_setopt($this->ch, CURLOPT_BUFFERSIZE, $buffer); 
    return $this; 
    } 

    public function includeHeader() { 
    curl_setopt($this->ch, CURLOPT_HEADER, true); 
    return $this; 
    } 
    public function excludeHeader() { 
    curl_setopt($this->ch, CURLOPT_HEADER, false); 
    return $this; 
    } 

    public function includeBody() { 
    curl_setopt($this->ch, CURLOPT_NOBODY, false); 
    return $this; 
    } 
    public function excludeBody() { 
    curl_setopt($this->ch, CURLOPT_NOBODY, true); 
    return $this; 
    } 

    public function setMaxRedirects($redirects = 4) { 
    if ($this->is_safe_mode()) { 
     return $this; 
    } 
    curl_setopt($this->ch, CURLOPT_MAXREDIRS, $redirects); 
    return $this; 
    } 

    public function followLocation() { 
    if ($this->is_safe_mode()) { 
     return $this->unfollowLocation(); 
    } 
    curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true); 
    return $this; 
    } 
    public function unfollowLocation() { 
    curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, false); 
    return $this; 
    } 

    public function setReferer($referer = null) { 
    curl_setopt($this->ch, CURLOPT_REFERER, $referer); 
    return $this; 
    } 

    public function setBinaryTransfer($binary = false) { 
    curl_setopt($this->ch, CURLOPT_BINARYTRANSFER, $binary); 
    return $this; 
    } 

    public function setTimout($timeout) { 
    curl_setopt($this->ch, CURLOPT_TIMEOUT, $timeout); 
    return $this; 
    } 

    public function setConnTimout($timeout) { 
    curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, $timeout); 
    return $this; 
    } 

    public function setUserAgent($userAgent = null) { 
    $userAgent = (!$userAgent) ? "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31" : $userAgent; 
    curl_setopt($this->ch, CURLOPT_USERAGENT, $userAgent); 
    return $this; 
    } 

    public function setProxy($url = null, $port = 0, $username = null, $password = null) { 
    curl_setopt($this->ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC); 
    curl_setopt($this->ch, CURLOPT_PROXY, $url.(($port) > 0 ? ":".$port : null)); 

    if ($port > 0) { 
     curl_setopt($this->ch, CURLOPT_PROXYPORT, $port); 
    } 

    if ($username) { 
     curl_setopt($this->ch, CURLOPT_PROXYUSERPWD, $username.":".$password); 
    } 

    return $this; 
    } 

    public function setAuth($username = null, $password = null) { 
    curl_setopt($this->ch, CURLOPT_USERPWD, $username.':'.$password); 
    return $this; 
    } 

    public function setCookiFile($file = "cookie.txt") { 
    if (!$file) { 
     return $this; 
    } 
    curl_setopt($this->ch, CURLOPT_COOKIEJAR, $file); 
    curl_setopt($this->ch, CURLOPT_COOKIEFILE, $file); 
    return $this; 
    } 

    public function verifySSL($ssl = false) { 
    if (!$ssl) { 
     curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false); 
     curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 2); 
    } 
    else { 
     curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, true); 
    } 
    return $this; 
    } 

    public function setPost($postFields = null, $keep_array = false) { 
    if (is_array($postFields) && !$keep_array) { 
     $postFields = http_build_query($postFields); 
    } 

    curl_setopt($this->ch, CURLOPT_POST, true); 
    curl_setopt($this->ch, CURLOPT_POSTFIELDS, $postFields); 

    return $this; 
    } 

    public function setFile($file = null) { 
    if ($file !== null) { 
     $file = realpath($file); 
    } 
    if ($file && is_readable($file)) { 
     $fp = fopen($file, "w"); 
     curl_setopt($this->ch, CURLOPT_FILE, $fp); 
    } 

    return $this; 
    } 

    public function setHeader($header = array("Expect:")) { 
    curl_setopt($this->ch, CURLOPT_HTTPHEADER, $header); 
    return $this; 
    } 

    public function createCurl($url = null) { 
    $url = ($url) ? trim($url) : trim($this->url); 

    if (!$url) { 
     throw new Exception("Fatal Error: you must provide a valid url before calling 'createCurl'"); 
    } 
    curl_setopt($this->ch, CURLOPT_URL, $url); 

    $this->_webpage = curl_exec($this->ch); 
    $this->_status = (int)curl_getinfo($this->ch, CURLINFO_HTTP_CODE); 
    $this->_error = (int)curl_errno($this->ch); 
    $this->_errmsg = curl_error($this->ch); 
    $this->_header = curl_getinfo($this->ch); 

    if (!$this->_errmsg) { 
     $this->_errmsg = $this->parse_http_code($this->_status); 
    } 

    return $this; 
    } 

    private function parse_http_code($code = 404) { 
    $code = (int)$code; 
    if (!class_exists("ipStatusCodes")) { 
     return null; 
    } 
    return ipStatusCodes::info($code); 
    } 

    private function is_safe_mode() { 
    return (@ini_get('open_basedir') != '' && @ini_get('safe_mode') != 'Off'); 
    } 

    public function getStatus() { 
    return $this->_status; 
    } 

    public function getResponse() { 
    return $this->_webpage; 
    } 

    public function getHeader() { 
    return $this->_header; 
    } 

    public function getError() { 
    return $this->_error; 
    } 

    public function getErrorMessage() { 
    return $this->_errmsg; 
    } 
} 
?> 

我不強迫你用我的班,你可以簡單地使用它這樣也...

<?php 
    curl_setopt($ch, CURLOPT_WRITEFUNCTION, "my_callback"); 
    function my_callback() { 
    // same like the "my_read_callback" function in my above code 
    } 
?> 
+1

丟失的關鍵信息片段是讓回調返回-1,這會觸發錯誤並中止傳輸。 – goat

+0

@chris它的工作正常,如果'CURLINFO_CONTENT_LENGTH_DOWNLOAD'返回長度爲'-1',只是現在檢查:)沒有錯誤,得到響應正文:) – bystwn22

+0

回調選項('CURLOPT_HEADERFUNCTION','CURLOPT_READFUNCTION','CURLOPT_WRITEFUNCTION'和'CURLOPT_PROGRESSFUNCTION')正是我所需要的!我不知道他們是如此+1並接受。謝謝! – zuza

0

,捲曲頭可以seperatly你執行的是請求後讀取。通過執行以下代碼

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_VERBOSE, 1); 
curl_setopt($ch, CURLOPT_HEADER, 1); 

// Then, after your curl_exec call: 
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 
$header = substr($response, 0, $header_size); 
$body = substr($response, $header_size); 
+0

這不是我所問的。 – zuza

+0

這是做 – DevZer0

+0

的唯一途徑下載一個2GB的AVI文件是學習它的'內容type'是'視頻/ avi'的唯一途徑?不是真的。 – zuza