在使用PHP 進行網絡請求時, cURL擴展無疑是最常見、最強大的工具之一。而在cURL的日常使用中, curl_setopt()用於設置請求選項, curl_close()用於關閉會話句柄,看起來簡單明了,但它們一起使用時卻隱藏著不少“坑”。本文將深入剖析幾個常見的錯誤使用方式,幫助你避免中招。
$ch = curl_init();
curl_close($ch);
curl_setopt($ch, CURLOPT_URL, "https://gitbox.net/api/data");
問題分析:一旦調用了curl_close() ,這個$ch句柄就已經被釋放了,後續再對它進行任何設置都是無效的,甚至可能拋出警告。
解決方案:應確保在調用curl_close()之前完成所有請求及處理工作。 curl_close()應該是你整個請求流程的最後一步。
許多開發者會嘗試復用句柄以提高性能,但一不小心在關閉後繼續使用就會出錯:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://gitbox.net/api/one");
curl_exec($ch);
curl_close($ch);
// 再次使用
curl_setopt($ch, CURLOPT_URL, "https://gitbox.net/api/two");
curl_exec($ch);
問題分析:關閉之後的$ch是一個無效資源,繼續使用會導致PHP 拋出錯誤: supplied resource is not a valid cURL handle resource 。
建議做法:如果要發起多個請求,不要在第一次請求後立刻關閉句柄,或者使用多個句柄,或者在每次使用時都重新初始化。
$ch = curl_init("https://gitbox.net/api/data");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
$result = curl_exec($ch);
curl_close($ch);
echo "結果為:" . $result;
問題分析:沒有設置CURLOPT_RETURNTRANSFER為true ,導致結果被直接輸出到了頁面,而$result其實是true或false ,並非真正的返回內容。
正確做法:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
這樣才能獲取返回內容進行後續處理,比如json 解碼、字符串分析等。
很多人在關閉前忽略了檢查錯誤:
$ch = curl_init("https://gitbox.net/api/info");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
if (!$data) {
echo "請求失敗";
}
問題分析: curl_exec()返回false 表示失敗,但更重要的是curl_error($ch)提供了詳細的錯誤信息,一旦curl_close()執行後,再也無法獲取錯誤描述。
建議做法:
$data = curl_exec($ch);
if (curl_errno($ch)) {
echo 'cURL 錯誤:' . curl_error($ch);
}
curl_close($ch);
先判斷錯誤,再關閉句柄,這是良好的編碼習慣。
$ch = curl_init("https://gitbox.net/secure/data");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
問題分析:如果目標是HTTPS 且沒有設置CURLOPT_SSL_VERIFYPEER ,可能會在某些環境下失敗。
建議做法:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // 或 false(僅測試用)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
要根據實際部署環境設定,生產環境盡量啟用驗證。