资讯专栏INFORMATION COLUMN

PHP cURL请求详解

paney129 / 3156人阅读

摘要:不支持多进程,如果需要异步请求,非阻塞的方式,请选择。时会发送请求,类型为,是表单提交时最常见的一种。允许函数执行的最长秒数。设定请求中部分的内容。常规的使用来请求,功能强大,使用方便,按需配置。

在PHP后端的开发过程中,除了获取数据库的数据和处理数据的内部逻辑,往往还需要请求其他服务器接口的数据,我们一般有3种方式来获取数据,分别是:

file_get_contents

fsockopen

curl

3种常用的接口获取方式简述 file_get_contents

函数声明:

/** 函数作用:将整个文件读入字符串
    @param $filename 读取的文件名或url,如果是文件路径,$use_include_path需置为true
    @param $use_include_path 是否使用文件目录路径查找,如果是文件查找,需要置为true,默认为false
    @param $context 资源参数,使用stream_context_create创造的一个上下文,用于配置读取文件的参数,如配置HTTP请求的方法和头部信息
    @param $offset 开始读取数据的偏移值
    @param $maxlen 从$offset开始获取多长的数据
    @return string 如果成功返回字符串,失败返回false
*/
string file_get_contents(string $filename, bool $use_include_path = false, resource $context, int $offset = -1, int $maxlen)

实例获取数据:

// 笔者开发使用Yii2,所以路由控制器使用action的写法
public function actionFetch() {
    // 该url为笔者写的另外一篇文章,测试用
    $data = file_get_contents("https://segmentfault.com/a/1190000011549088");
    // 获取到的数据需要输出我们才能在前端请求看到返回的结果
    echo $data;
    // 结束本次请求
    return $data;
}
fsockopen

函数声明:

/** 函数作用:打开一个网络连接或者一个Unix套接字连接
    @param $hostname 初始化套接字连接到的主机
    @param $port 端口号,如果不传递,则不实用端口
    @param $errno 
    @param $errstr 字符串形式的错误信息
    @param $timeout 超时时间,单位为s
    @return resource 如果成功返回文件句柄,可以使用文件函数读写,失败返回false
*/
resource fsockopen(string $hostname, int $port = -1, int &$errno, string &$errstr, float $timeout = ini_get("default_socket_timeout"))

实例获取数据:

注意:在我的测试环境中报错:`Unable to find the socket transport "http" - did you
forget to enable it when you configured
PHP?`,是由于php.ini配置问题,所以不推荐此种方法获取,因为受配置文件影响,很容易不可用。
// 笔者开发使用Yii2,所以路由控制器使用action的写法
$fp = fsockopen("https://segmentfault.com/a/1190000011549088", 80);
if (!$fp) {
    echo "$errstr ($errno)
"; } else { $out = "GET / HTTP/1.1 "; $out .= "Host: www.example.com "; $out .= "Connection: Close "; fwrite($fp, $out); while (!feof($fp)) { echo fgets($fp, 128); } fclose($fp); }
cURL
需要安装libcurl包。
cURL全称commandLine Uniform Resource Locator,命令行统一资源定位器,用于在命令行上传和下载url文件。提供用于程序开发的libcurl包。

实例获取数据:

// 初始化一个curl资源
$ch = curl_init("https://segmentfault.com/a/1190000011549088");
// 执行该curl对象,返回结果
$data = curl_exec($ch);
// 关闭cURL资源,释放系统资源
curl_close($ch);
3种方式的优劣对比

在代码风格上,file_get_contents最为简洁,fsockopencurl比较复杂。

在配置头部信息上:
file_get_contents通过stream_context_set_option() 来配置头部信息;
fsockopen可以通过fwirte ($socket, $config)的方式或字符串拼接配置请求头部信息,支持异步请求;
curl可以通过curl_setopt($curl, $name, $key)的方式配置请求配置,作为lib库,功能强大。

PHP不支持多进程,如果需要异步请求,非阻塞的方式,请选择fsockopen
常规的请求我们使用file_get_contentscurl,除了功能外,下面做一个性能测试:

$url = "https://segmentfault.com/a/1190000011549088";

// 100次file_get_contents请求,结果为113s
$start = time();
for ($i = 0; $i < 100; $i++) {
    $data = file_get_contents($url);
}
$end = time();
$cost = $end - $start;
echo "file_get_contents 100次总耗时:", "$cost";

// 100次curl请求,结果为48s
$start = time();
for ($i = 0; $i < 100; $i++) {
    $ch = curl_init($url);
    // 设置不直接输出结果,而是保存到$data中
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($ch);
}
$end = time();
$cost = $end - $start;
echo "curl 100次总耗时:", "$cost";

所以,在常规PHP请求中,我们使用curl的方式来请求接口数据。

cURL详解

curl的基本使用方法就是:

curl_init()初始化cURL会话

curl_setopt()curl_setopt_array()设置配置选项

curl_exec()执行会话

curl_close()关闭会话

curl_init()

函数声明:

/** 函数作用:初始化curl会话
    @param $url 配置中的请求url,如果不传递,需要在curl_setopt()设置CURLOPT_URL
    @return resource 如果成功返回cURL句柄,失败返回false
*/
resource curl_init([string $url = NULL])
curl_setopt()curl_setopt_array()

函数声明:

/** 函数作用:设置cURL传输选项
    @param $ch curl_init()返回的cURL句柄
    @param $option 需要设置的CURLOPT_XXX选项
    @param $value 在option选项上设置的值
    @return bool 成功返回true,失败返回false
*/
bool curl_setopt(resource $ch, int $option, mixed $value)

/** 函数作用:设置cURL传输选项
    @param $ch curl_init()返回的cURL句柄
    @param $options 需要设置的CURLOPT_XXX选项和值的数组
    @return bool 全部成功返回true,一个失败立刻返回false
*/
bool curl_setopt_array(resource $ch, array $options)

使用实例:

// 设置url和不直接输出结果,单项设置
curl_setopt($ch, CURLOPT_URL, "https://segmentfault.com/a/1190000011549088");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// 批量设置
curl_setopt_array($ch, array(
    CURLOPT_URL => "https://segmentfault.com/a/1190000011549088",
    CURLOPT_RETURNTRANSFER => true
));
CURLOPT_参数

列举一些常用的参数,全部参数可以在 PHP curl参数文档 查阅。

CURLOPT_HEADER 启用时会将头文件的信息作为数据流输出。

CURLOPT_POST TRUE 时会发送 POST 请求,类型为:application/x-www-form-urlencoded,是 HTML 表单提交时最常见的一种。

CURLOPT_RETURNTRANSFER TRUE 将curl_exec()获取的信息以字符串返回,而不是直接输出。

CURLOPT_UPLOAD TRUE 准备上传。

CURLOPT_CONNECTTIMEOUT 在尝试连接时等待的秒数。设置为0,则无限等待。

CURLOPT_PORT 用来指定连接端口。

CURLOPT_TIMEOUT 允许 cURL 函数执行的最长秒数。

CURLOPT_COOKIE 设定 HTTP 请求中"Cookie: "部分的内容。多个 cookie 用分号分隔,分号后带一个空格(例如, "fruit=apple; colour=red")。

CURLOPT_POSTFIELDS 全部数据使用HTTP协议中的 "POST" 操作来发送。该参数只支持一维数组,如果需要传递多维数组,需要使用http_build_query处理,更详细的信息可以查看PHP cURL请求中CURLOPT_POSTFIELDS只支持一维数组这篇文章。

CURLOPT_URL 需要获取的 URL 地址,也可以在curl_init() 初始化会话的时候。

curl_exec()

函数声明:

/** 函数作用:执行curl会话
    @param $ch curl_init()返回的cURL句柄
    @return mixed 成功返回true,失败返回false;如果设置了CURLOPT_RETRUNTRANSFER为ture,成功返回执行结果
*/
mixed curl_exec(resource $ch)
curl_close()

函数声明:

/** 函数作用:关闭curl会话
    @param $ch curl_init()返回的cURL句柄
    @return void
*/
void curl_close(resource $ch)
curl请求封装
public static function parseApi($vars = Array(), $timeout = 60, $uri = "") {
    // 初始化curl
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $uri);
    // 支持POST请求
    curl_setopt($ch, CURLOPT_POST, 1);
    // 不直接输出,返回到变量
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    // 设置POST参数
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($vars));
    // 设置超时,防止机器被大量超时请求卡死
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    // 请求数据
    $response = curl_exec($ch);
    // 关闭请求
    curl_close($ch);
    // 对数据进行编码,方便前后端数据处理
    $result = json_decode($response, true);
    // PHP返回数据
    return $result;
}
PHP cURL并行请求

除了上面的curl_init之外,cURL还支持curl_multi_init并行请求,允许我们同时请求上百个接口,而不是foreach轮询阻塞式的请求。详细的可以查看我的另一篇文章:PHP实现并发请求。

总结

如果你需要非阻塞的请求,可以使用fsockopen()方法。
常规的使用curl来请求,功能强大,使用方便,按需配置。

参考资料

PHP手册 file_get_contents: http://php.net/manual/zh/func...

PHP手册 stream_context_create: http://php.net/manual/zh/func...

PHP手册 fsockopen: http://php.net/manual/zh/func...

百度百科 curl: https://baike.baidu.com/item/...

维基百科 curl: https://zh.wikipedia.org/wiki...

PHP手册 curl函数:http://php.net/manual/zh/ref....

博客园 fsockopen实现异步请求:http://www.cnblogs.com/52fhy/...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30815.html

相关文章

  • PHP使用CURL详解

    摘要:使用详解是一个非常强大的开源库,支持很多协议,包括等,我们使用它来发送请求。它给我们带来的好处是可以通过灵活的选项设置不同的协议参数,并且支持。可以根据前缀是还是自动选择是否加密发送内容。传输前准备耗时。上传内容的长度。 PHP使用CURL详解 Curl是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。它给我 们带来的好处是可以...

    yedf 评论0 收藏0
  • PHP实现并发请求

    摘要:不支持多线程模式和回调处理,因此内部脚本都是同步阻塞式的,如果你发起一个的请求,那么程序就会阻塞,直到请求返回结果,才会继续执行代码。参考资料手册手册预定义常量中实现多线程请求详解每次使用同时并发多少请求合适简书多线程及原理 后端服务开发中经常会有并发请求的需求,比如你需要获取10家供应商的带宽数据(每个都提供不同的url),然后返回一个整合后的数据,你会怎么做呢? 在PHP中,最直观...

    zhangfaliang 评论0 收藏0
  • [转]详解PHP设置定时任务的实现方法

    摘要:服务器定时任务服务器定时任务需要你是独立的服务器,或者是,总之就是对系统的配置有足够的权限,虚拟空间就不要折腾这个方法了,因为你没有权限。 文章转载自:问说网 » 详解PHP设置定时任务的实现方法地址:http://www.uedsc.com/php-timing-task.html 定时运行任务对于一个网站来说,是一个比较重要的任务,比如定时发布文档,定时清理垃圾信息等,现在的网站大...

    lemon 评论0 收藏0
  • PHP cURL请求CURLOPT_POSTFIELDS只支持一维数组

    摘要:使用发起请求时,我们会常用方法,具体的请求方式可以参考请求详解这篇文章。但我推荐,为了请求的规范化,应该全部使用对请求的参数进行编码。 使用PHP发起请求时,我们会常用cURL方法,具体的PHP请求方式可以参考 PHP cURL请求详解 这篇文章。 cURL发起POST请求 在使用中,如果你需要发送POST的请求,需要配置CURLOPT_POST和CURLOPT_POSTFIELDS...

    airborne007 评论0 收藏0
  • phpcurl实现http与https请求的方法

    这篇文章主要介绍了php之curl实现http与https请求的方法,分别讲述了PHP访问http网页与访问https网页的实例,以及相关的注意事项,需要的朋友可以参考下。 本文实例讲述了php之curl实现http与https请求的方法,分享给大家供大家参考。具体如下:通常来说,php的curl函数组可以帮助我们把机器伪装成人的行为来抓取网站,下面来分享两个例子,一个是访问http网页,一个访问...

    loonggg 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<