使用curl是很常見的網(wǎng)絡(luò)請求方式,而在php中使用curl也非常的簡單,但是在實(shí)際應(yīng)用中,有時(shí)候會遇到curl卡死的問題,這時(shí)候需要我們找出問題所在并加以解決。
首先,我們需要確定curl是在哪個(gè)時(shí)候卡死的,是在請求時(shí)就卡住了還是在回調(diào)函數(shù)中卡住了。如果是在請求時(shí)就卡住了,我們可以檢查網(wǎng)絡(luò)狀況或者數(shù)據(jù)傳輸問題,如果是在回調(diào)函數(shù)中卡住了,就需要我們進(jìn)一步分析代碼。
比如,有時(shí)候我們使用curl時(shí)會將回調(diào)函數(shù)寫成一個(gè)類的方法來進(jìn)行處理。在這種情況下,我們的類有可能會在處理回調(diào)函數(shù)時(shí)出現(xiàn)死循環(huán)導(dǎo)致curl卡住。例如:
class RequestHandler { private $result; public function handle($ch, $data) { $this->result .= $data; curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'handle')); return strlen($data); } } $ch = curl_init(); $url = "http://www.example.com"; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $handler = new RequestHandler(); curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($handler, 'handle')); $response = curl_exec($ch);
上述代碼中,handle()方法會在每次請求結(jié)果返回后被調(diào)用。但是由于handle()方法中調(diào)用了curl_setopt()方法,導(dǎo)致curl的回調(diào)函數(shù)發(fā)生了死循環(huán),最終導(dǎo)致curl卡住。解決辦法是將curl_setopt()方法移動到curl_init()方法之后,防止回調(diào)函數(shù)無限遞歸。
另外,使用curl時(shí),我們需要注意服務(wù)器返回的HTTP頭信息中是否包含Expect頭信息。如果包含Expect頭信息,則curl會在發(fā)送完HTTP頭之后等待服務(wù)器返回100狀態(tài)碼,接著才會發(fā)送HTTP實(shí)體。在處理大量數(shù)據(jù)時(shí),這種等待會導(dǎo)致curl卡住。解決辦法是使用curl_setopt()方法禁用Expect頭信息,例如:
$ch = curl_init(); $url = "http://www.example.com"; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Expect:")); $response = curl_exec($ch);
除此之外,我們也可以使用超時(shí)處理來解決curl卡死的問題。使用curl_setopt()方法設(shè)置CURLOPT_TIMEOUT值可以控制curl請求的超時(shí)時(shí)間,例如:
$ch = curl_init(); $url = "http://www.example.com"; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 3); $response = curl_exec($ch);
以上代碼設(shè)置了請求超時(shí)時(shí)間為3秒,如果在該時(shí)間內(nèi)未接收到服務(wù)器返回的數(shù)據(jù),則會結(jié)束該請求。
綜上所述,curl php卡死是一個(gè)比較常見的問題,原因可能是代碼寫的有問題,也可能是網(wǎng)絡(luò)環(huán)境有問題。我們需要根據(jù)具體情況進(jìn)行分析,從而找出解決方案,保證curl請求能夠正常處理。