PHP Conference Japan 2024

curl_exec

(PHP 4 >= 4.0.2, PHP 5, PHP 7, PHP 8)

curl_exec執行 cURL 工作階段

說明

curl_exec(CurlHandle $handle): 字串|布林值

執行指定的 cURL 工作階段。

這個函式應該在初始化 cURL 工作階段並設定所有工作階段選項後呼叫。

參數

handle

curl_init() 返回的 cURL 句柄。

返回值

如果成功,此函數會將結果直接輸出到 stdout 並返回 true,失敗則返回 false。但是,如果設定了 CURLOPT_RETURNTRANSFER 選項,則成功時會返回結果,失敗時返回 false

警告

此函數可能返回布林值 false,但也可能返回評估為 false 的非布林值。請閱讀關於 布林值 的章節以了解更多資訊。使用 === 運算子 來測試此函數的返回值。

注意:

請注意,表示錯誤的回應狀態碼(例如 404 Not found)不被視為失敗。可以使用 curl_getinfo() 來檢查這些狀態碼。

更新日誌

版本 說明
8.0.0 handle 現在需要一個 CurlHandle 實例;以前需要的是 resource

範例

範例 #1 取得網頁

<?php
// 建立新的 cURL 資源
$ch = curl_init();

// 設定 URL 和其他適當的選項
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);

// 抓取 URL 並傳遞給瀏覽器
curl_exec($ch);

// 關閉 cURL 資源並釋放系統資源
curl_close($ch);
?>

參見

新增註解

使用者貢獻的註解 9 則註解

來自 Code2Design.com 的 David
14 年前
如果有人正在尋找一些簡單的函數 [以協助自動化 POST 和 GET 查詢的 cURL 流程],我想我會發布這些函數。

<?php

/**
* Send a POST requst using cURL
* @param string $url to request
* @param array $post values to send
* @param array $options for cURL
* @return string
*/
function curl_post($url, array $post = NULL, array $options = array())
{
$defaults = array(
CURLOPT_POST => 1,
CURLOPT_HEADER => 0,
CURLOPT_URL => $url,
CURLOPT_FRESH_CONNECT => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FORBID_REUSE => 1,
CURLOPT_TIMEOUT => 4,
CURLOPT_POSTFIELDS => http_build_query($post)
);

$ch = curl_init();
curl_setopt_array($ch, ($options + $defaults));
if( !
$result = curl_exec($ch))
{
trigger_error(curl_error($ch));
}
curl_close($ch);
return
$result;
}

/**
* Send a GET requst using cURL
* @param string $url to request
* @param array $get values to send
* @param array $options for cURL
* @return string
*/
function curl_get($url, array $get = NULL, array $options = array())
{
$defaults = array(
CURLOPT_URL => $url. (strpos($url, '?') === FALSE ? '?' : ''). http_build_query($get),
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 4
);

$ch = curl_init();
curl_setopt_array($ch, ($options + $defaults));
if( !
$result = curl_exec($ch))
{
trigger_error(curl_error($ch));
}
curl_close($ch);
return
$result;
}
?>
匿名
18 年前
使用 curl_exec() 和 CURLOPT_RETURNTRANSFER 選項時要小心。根據手冊和各種文件
將 CURLOPT_RETURNTRANSFER 設定為 TRUE,curl_exec() 的返回值會以字串形式返回,而不是直接輸出。

當擷取沒有內容的檔案(例如 0 位元組的檔案)時,curl_exec() 會返回 bool(true),而不是空字串。我在手冊中沒有看到任何相關說明。

重現此問題的程式碼範例
<?php

// 假設的 URL,指向一個存在的空檔案(例如 0 位元組檔案)
$url = 'http://www.example.com/empty_file.txt';

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);

// 執行並返回字串(這應該是一個空字串 '')
$str = curl_exec($curl);

curl_close($curl);

// $str 的值實際上是 bool(true),而不是空字串 ''
var_dump($str);

?>
turiyag
7 年前
不要停用 SSL 驗證! 你不需要這樣做,而且保持安全非常容易! 如果你發現關閉「CURLOPT_SSL_VERIFYHOST」和「CURLOPT_SSL_VERIFYPEER」解決了你的問題,很可能你只是在 Windows 系統上。 只需 2 分鐘即可解決問題。 逐步說明如下:

https://snippets.webaware.com.au/howto/stop-turning-off-curlopt_ssl_verifypeer-and-fix-your-php-config/
jpatta at digitalgamesystems dot com
3 年前
如果你想除錯 curl_exec,你可能希望記錄它的詳細資訊,並分析其執行期間的各個時間點。

在 curl_exec 之前

<?php
// 這會產生一個 curl 記錄檔
curl_setopt($curl, CURLOPT_VERBOSE, true);
curl_setopt($curl, CURLOPT_STDERR, fopen('/your/writable/app/logdir/curl.log', 'a+')); // a+ 表示附加...
?>

在 curl_exec 之後,但在 curl_close 之前

<?php
// 擷取時間資訊
extract(curl_getinfo($curl)); // 從 getinfo 建立指標變數
$appconnect_time = curl_getinfo($curl, CURLINFO_APPCONNECT_TIME); // 明確請求此時間
$downloadduration = number_format($total_time - $starttransfer_time, 9); // 格式化,以避免科學記數法
$namelookup_time = number_format($namelookup_time, 9);
$metrics = "CURL...: $url 時間...: $total_time DNS: $namelookup_time 連線: $connect_time SSL/SSH: $appconnect_time 傳輸前: $pretransfer_time 開始傳輸: $starttransfer_time 下載: $downloadduration";
error_log($metrics); // 寫入 php-fpm 預設的 www-error.log,或者使用 file_put_contents(<檔名>, $metrics, FILE_APPEND) 將其附加到與上述相同的日誌檔
?>

除錯愉快
roman dot ivasyuk at gmail dot com
16 年前
<?php
class CurlRequest
{
private
$ch;
/**
* Init curl session
*
* $params = array('url' => '',
* 'host' => '',
* 'header' => '',
* 'method' => '',
* 'referer' => '',
* 'cookie' => '',
* 'post_fields' => '',
* ['login' => '',]
* ['password' => '',]
* 'timeout' => 0
* );
*/
public function init($params)
{
$this->ch = curl_init();
$user_agent = 'Mozilla/5.0 (Windows; U;
Windows NT 5.1; ru; rv:1.8.0.9) Gecko/20061206 Firefox/1.5.0.9'
;
$header = array(
"Accept: text/xml,application/xml,application/xhtml+xml,
text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
,
"Accept-Language: ru-ru,ru;q=0.7,en-us;q=0.5,en;q=0.3",
"Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7",
"Keep-Alive: 300");
if (isset(
$params['host']) && $params['host']) $header[]="Host: ".$host;
if (isset(
$params['header']) && $params['header']) $header[]=$params['header'];

@
curl_setopt ( $this -> ch , CURLOPT_RETURNTRANSFER , 1 );
@
curl_setopt ( $this -> ch , CURLOPT_VERBOSE , 1 );
@
curl_setopt ( $this -> ch , CURLOPT_HEADER , 1 );

if (
$params['method'] == "HEAD") @curl_setopt($this -> ch,CURLOPT_NOBODY,1);
@
curl_setopt ( $this -> ch, CURLOPT_FOLLOWLOCATION, 1);
@
curl_setopt ( $this -> ch , CURLOPT_HTTPHEADER, $header );
if (
$params['referer']) @curl_setopt ($this -> ch , CURLOPT_REFERER, $params['referer'] );
@
curl_setopt ( $this -> ch , CURLOPT_USERAGENT, $user_agent);
if (
$params['cookie']) @curl_setopt ($this -> ch , CURLOPT_COOKIE, $params['cookie']);

if (
$params['method'] == "POST" )
{
curl_setopt( $this -> ch, CURLOPT_POST, true );
curl_setopt( $this -> ch, CURLOPT_POSTFIELDS, $params['post_fields'] );
}
@
curl_setopt( $this -> ch, CURLOPT_URL, $params['url']);
@
curl_setopt ( $this -> ch , CURLOPT_SSL_VERIFYPEER, 0 );
@
curl_setopt ( $this -> ch , CURLOPT_SSL_VERIFYHOST, 0 );
if (isset(
$params['login']) & isset($params['password']))
@
curl_setopt($this -> ch , CURLOPT_USERPWD,$params['login'].':'.$params['password']);
@
curl_setopt ( $this -> ch , CURLOPT_TIMEOUT, $params['timeout']);
}

/**
* Make curl request
*
* @return array 'header','body','curl_error','http_code','last_url'
*/
public function exec()
{
$response = curl_exec($this->ch);
$error = curl_error($this->ch);
$result = array( 'header' => '',
'body' => '',
'curl_error' => '',
'http_code' => '',
'last_url' => '');
if (
$error != "" )
{
$result['curl_error'] = $error;
return
$result;
}

$header_size = curl_getinfo($this->ch,CURLINFO_HEADER_SIZE);
$result['header'] = substr($response, 0, $header_size);
$result['body'] = substr( $response, $header_size );
$result['http_code'] = curl_getinfo($this -> ch,CURLINFO_HTTP_CODE);
$result['last_url'] = curl_getinfo($this -> ch,CURLINFO_EFFECTIVE_URL);
return
$result;
}
}
?>

使用範例
<?php
..........
try
{
$params = array('url' => 'http://www.google.com',
'host' => '',
'header' => '',
'method' => 'GET', // 'POST','HEAD'
'referer' => '',
'cookie' => '',
'post_fields' => '', // 'var1=value&var2=value
'timeout' => 20
);

$this->curl->init($params);
$result = $this->curl->exec();
if (
$result['curl_error']) throw new Exception($result['curl_error']);
if (
$result['http_code']!='200') throw new Exception("HTTP Code = ".$result['http_code']);
if (!
$result['body']) throw new Exception("Body of file is empty");
...............
}
catch (
Exception $e)
{
echo
$e->getMessage();
}
?>
hablutzel1 at gmail dot com
10 年前
永遠要注意,CURLOPT_SSL_VERIFYPEER 設定為 FALSE 或 0 永遠不應該用於正式環境,因為它會使連結立即受到中間人攻擊的威脅。您仍然可以在開發過程中使用它,但我建議只有在您知道自己在做什麼的情況下才這樣做,否則請花更多時間使對 HTTPS 網站的請求能夠正常運作,而不要將該選項設定為 FALSE 或 0。
lukasl at ackleymedia dot com
18 年前
感謝您的分享。我一直想知道為什麼我的結果是 1。

為了安全地解決這個問題,我用以下方式檢查結果是否有效。

$ch = curl_init(); /// 初始化一個 cURL 工作階段
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$xmlResponse = curl_exec ($ch);
curl_close ($ch);

if (!is_string($xmlResponse) || !strlen($xmlResponse)) {
return $this->_set_error( "連線伺服器失敗" );
} else {
return $xmlResponse;
}
nagyp at hunaxon dot hu
21 年前
僅供參考
無論 CURLOPT_RETURNTRANSFER 如何設定,如果在執行 curl 工作階段時發生錯誤,它都會返回 false。
Roland
4 年前
要檢查是否逾時或錯誤 -

if (!$responsexml || !is_string($responsexml) || !strlen($responsexml) || strpos($responsexml, 'upstream request timeout') !== false) {
返回 $this->sendRequest($request, $headers);
}
To Top