标题:学习CURL扩展功能的使用(一)
学习CURL扩展功能的使用(一)
其实 CURL 这个扩展本来也不打算写得,毕竟这个也是大家最常用的功能之一的。不过既然是在刷文档,学习到了就分享出来吧,不要陷入“知识的诅咒”。本身自己的知识体系就不完整,说不定也有很多小伙伴和我一样只是平常追求业务快速开发而简单地使用,并没有深入地去了解过。今天,我们就来深入地了解一下 CURL 吧。
PHP 的这个 CURL 扩展其实是基于的 libcurl 这个系统的扩展软件。在 linux 相关的系统中,这个软件基本就是标配的,像是 CentOS 、Ubuntu 这些都是装好系统就有的,不需要我们再单独安装这个 libcurl ,就算没有的话,也可以方便地安装到。
而对于 PHP 来说,这个扩展更是已经集成在了 PHP 的源码安装包中,只需要我们在编译安装 PHP 的时候加上 --with-curl 就可以了。
使用 CURL 请求链接
先来看看最简单地使用 CURL 来请求一个 GET 地址。
$ch = curl_init("https://www.baidu.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 检查证书中是否设置域名
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 信任任何证书
$res = curl_exec($ch);
$info = curl_getinfo($ch);
if(curl_error($ch)) {
var_dump(curl_error($ch));
}
var_dump($res);
// string(14722) "<!DOCTYPE html><!--STATUS OK-->
// <html>
// <head>
// <meta http-equiv="content-type" content="text/html;charset=utf-8">
// <meta http-equiv="X-UA-Compatible" content="IE=Edge">
// <link rel="dns-prefetch" href="//s1.bdstatic.com"/>
// <link rel="dns-prefetch" href="//t1.baidu.com"/>
// <link rel="dns-prefetch" href="//t2.baidu.com"/>
// <link rel="dns-prefetch" href="//t3.baidu.com"/>
// <link rel="dns-prefetch" href="//t10.baidu.com"/>
// <link rel="dns-prefetch" href="//t11.baidu.com"/>
// <link rel="dns-prefetch" href="//t12.baidu.com"/>
// <link rel="dns-prefetch" href="//b1.bdstatic.com"/>
// <title>百度一下,你就知道</title>
// ……………………
// ……………………
// ……………………
// </body></html>
// "
var_dump($info);
// array(37) {
// ["url"]=>
// string(21) "https://www.baidu.com"
// ["content_type"]=>
// string(9) "text/html"
// ["http_code"]=>
// int(200)
// ["header_size"]=>
// int(960)
// ["request_size"]=>
// int(52)
// ["filetime"]=>
// int(-1)
// ["ssl_verify_result"]=>
// int(0)
// ["redirect_count"]=>
// int(0)
// ["total_time"]=>
// float(0.127654)
// ["namelookup_time"]=>
// float(0.004669)
// ["connect_time"]=>
// float(0.030823)
// ["pretransfer_time"]=>
// float(0.100782)
// ["size_upload"]=>
// float(0)
// ["size_download"]=>
// float(14722)
// ["speed_download"]=>
// float(115921)
// ["speed_upload"]=>
// float(0)
// ["download_content_length"]=>
// float(14722)
// ["upload_content_length"]=>
// float(-1)
// ["starttransfer_time"]=>
// float(0.127519)
// ["redirect_time"]=>
// float(0)
// ["redirect_url"]=>
// string(0) ""
// ["primary_ip"]=>
// string(15) "183.232.231.172"
// ["certinfo"]=>
// array(0) {
// }
// ["primary_port"]=>
// int(443)
// ["local_ip"]=>
// string(13) "192.168.51.11"
// ["local_port"]=>
// int(52795)
// ["http_version"]=>
// int(2)
// ["protocol"]=>
// int(2)
// ["ssl_verifyresult"]=>
// int(0)
// ["scheme"]=>
// string(5) "HTTPS"
// ["appconnect_time_us"]=>
// int(100710)
// ["connect_time_us"]=>
// int(30823)
// ["namelookup_time_us"]=>
// int(4669)
// ["pretransfer_time_us"]=>
// int(100782)
// ["redirect_time_us"]=>
// int(0)
// ["starttransfer_time_us"]=>
// int(127519)
// ["total_time_us"]=>
// int(127654)
// }
curl_close($ch);
标准的 CURL 套路其实就是三步。curl_init() 打开一个句柄,句柄中包含 URL 地址,curl_exec() 执行句柄输出或返回结果,curl_close() 关闭句柄。为什么说 curl_exec() 是输出或者返回结果呢?因为如果在默认的情况下,curl_exec() 是会像 phpinfo() 这类函数一样直接打印输出结果的,我们需要使用 curl_setopt() 设置 CURLOPT_RETURNTRANSFER 这个常量为 true 或 1 来让 curl_exec() 将访问结果作为返回值进行返回,而不是直接输出。由此可以看出,curl_setopt() 也是 CURL 中非常重要的一个函数。其实它的作用就是为这个 CURL 句柄设置各种配置参数,包括我们在代码中看到的 CURLOPT_SSL_VERIFYHOST 和 CURLOPT_SSL_VERIFYPEER 就是为 HTTPS 链接的访问而准备的配置参数,以及后面我们要看到的 POST 请求也是需要使用 curl_setopt() 来实现的。
curl_exec() 返回的是访问的 URL 返回的结果,curl_getinfo() 返回的则是这个请求一些详细信息,比如我们可以看到请求的 url 地址、Content-Type 类型、http_code 等信息,对于一些业务需求判断来说,这些信息非常重要。curl_error() 则是在本次请求中的错误信息的显示,如果产生了错误,错误信息就可以通过这个函数获取到。
POST 请求
GET 请求是非常简单的,当然,POST 请求也不复杂,就像前面说的,只是配置参数有一些变化而已。
$ch = curl_init("http://localhost:9001");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt_array($ch, [
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => ['a'=>'post测试'],
]);
$res = curl_exec($ch);
$info = curl_getinfo($ch);
if(curl_error($ch)) {
var_dump(curl_error($ch));
}
var_dump($res);
// string(22) "测试数据post测试"
curl_close($ch);
在这里,我们用了一个新的函数 curl_setopt_array() ,其实就是可以更加方便地使用数组来定义配置参数而已,和一个一个地写 curl_setopt() 没有什么区别,只是更加地方便。我们只需要指定 CURLOPT_POST 为 true 或 1,然后通过 CURLOPT_POSTFIELDS 为 POST 参数赋值就可以了,是不是也非常简单。
CURL 的字符串 URL 编码
之前我们已经学习过一些编码相关的函数,在 CURL 扩展中,也有对应的 URL 编码函数,其实它和使用 urlencode() 并没有什么太大的区别。
$ch = curl_init("http://localhost:9001");
$str = "测试编码";
$escapeStr = curl_escape($ch, $str);
var_dump($escapeStr); // string(36) "%E6%B5%8B%E8%AF%95%E7%BC%96%E7%A0%81"
var_dump(curl_unescape($ch, $escapeStr)); // string(12) "测试编码"
curl_close($ch);
使用 curl_escape() 就可以对数据进行 URL 编码,使用 curl_unescape() 就可以非常方便地实现解码。不过,这两个函数是必须要一个 CURL 句柄参数的,也就是说,它们不能脱离 CURL 来直接使用。我们日常开发还是使用 urlencode() 这类更为通用的函数就好了。
查看 CURL 的版本号
最后,我们再学习一个非常简单的函数,就是查看一下当前系统的 CURL 版本情况以及一些相关的软件信息,比如支持的协议列表之类的内容。
var_dump(curl_version());
// array(16) {
// ["version_number"]=>
// int(475648)
// ["age"]=>
// int(5)
// ["features"]=>
// int(11519901)
// ["ssl_version_number"]=>
// int(0)
// ["version"]=>
// string(6) "7.66.0"
// ["host"]=>
// string(25) "x86_64-apple-darwin19.5.0"
// ["ssl_version"]=>
// string(14) "OpenSSL/1.1.1d"
// ["libz_version"]=>
// string(6) "1.2.11"
// ["protocols"]=>
// array(23) {
// [0]=>
// string(4) "dict"
// [1]=>
// string(4) "file"
// [2]=>
// string(3) "ftp"
// [3]=>
// string(4) "ftps"
// [4]=>
// string(6) "gopher"
// [5]=>
// string(4) "http"
// [6]=>
// string(5) "https"
// [7]=>
// string(4) "imap"
// [8]=>
// string(5) "imaps"
// [9]=>
// string(4) "ldap"
// [10]=>
// string(5) "ldaps"
// [11]=>
// string(4) "pop3"
// [12]=>
// string(5) "pop3s"
// [13]=>
// string(4) "rtmp"
// [14]=>
// string(4) "rtsp"
// [15]=>
// string(3) "scp"
// [16]=>
// string(4) "sftp"
// [17]=>
// string(3) "smb"
// [18]=>
// string(4) "smbs"
// [19]=>
// string(4) "smtp"
// [20]=>
// string(5) "smtps"
// [21]=>
// string(6) "telnet"
// [22]=>
// string(4) "tftp"
// }
// ["ares"]=>
// string(6) "1.15.0"
// ["ares_num"]=>
// int(69376)
// ["libidn"]=>
// string(5) "2.2.0"
// ["iconv_ver_num"]=>
// int(0)
// ["libssh_version"]=>
// string(13) "libssh2/1.9.0"
// ["brotli_ver_num"]=>
// int(16777223)
// ["brotli_version"]=>
// string(5) "1.0.7"
// }
总结
就像文章开头所说的,CURL 的内容其实并不复杂,核心的就那几步,它最复杂的部分是在于非常多的配置常量信息,而且这些信息并不是太好记,掌握常用的就可以了,后面我们还将继续讲解 CURL 中其它的内容,不要错过哦。
测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/2021/02/source/4.学习CURL扩展功能的使用(一).php
参考文档:
https://www.php.net/manual/zh/ref.curl.php