2024年PHP开发者大会日本站

curl_exec

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

curl_exec执行cURL会话

描述

curl_exec(CurlHandle $handle): string|bool

执行给定的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

/**
* 使用cURL发送POST请求
* @param string $url 要请求的URL
* @param array $post 要发送的值
* @param array $options 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;
}

/**
* 使用cURL发送GET请求
* @param string $url 要请求的URL
* @param array $get 要发送的值
* @param array $options 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 Time...: $total_time DNS: $namelookup_time Connect: $connect_time SSL/SSH: $appconnect_time PreTransfer: $pretransfer_time StartTransfer: $starttransfer_time Download: $downloadduration";
error_log($metrics); // 写入php-fpm默认的www-error.log,或者使用file_put_contents(<filename>, $metrics, FILE_APPEND)追加到上面相同的日志
?>

调试愉快
roman dot ivasyuk at gmail dot com
16年前
<?php
class CurlRequest
{
private
$ch;
/**
* 初始化curl会话
*
* $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']);
}

/**
* 执行curl请求
*
* @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年前
仅供参考
如果在执行 cURL 会话时出现错误,无论 CURLOPT_RETURNTRANSFER 如何设置,它都会返回 false。
Roland
4年前
检查超时或错误 -

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