在PHP后端的开发过程当中,除了获取数据库的数据和处理数据的内部逻辑,每每还须要请求其余服务器接口的数据,咱们通常有3种方式来获取数据,分别是:php
file_get_contents
fsockopen
curl
file_get_contents
函数声明:html
/** 函数做用:将整个文件读入字符串 @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"))
实例获取数据:json
注意:在个人测试环境中报错:`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)<br />\n"; } else { $out = "GET / HTTP/1.1\r\n"; $out .= "Host: www.example.com\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while (!feof($fp)) { echo fgets($fp, 128); } fclose($fp); }
cURL
须要安装libcurl
包。
cURL
全称commandLine Uniform Resource Locator
,命令行统一资源定位器,用于在命令行上传和下载url文件。提供用于程序开发的libcurl
包。
实例获取数据:segmentfault
// 初始化一个curl资源 $ch = curl_init('https://segmentfault.com/a/1190000011549088'); // 执行该curl对象,返回结果 $data = curl_exec($ch); // 关闭cURL资源,释放系统资源 curl_close($ch);
在代码风格上,file_get_contents
最为简洁,fsockopen
和curl
比较复杂。后端
在配置头部信息上:file_get_contents
经过stream_context_set_option()
来配置头部信息;fsockopen
能够经过fwirte ($socket, $config)
的方式或字符串拼接配置请求头部信息,支持异步请求;curl
能够经过curl_setopt($curl, $name, $key)
的方式配置请求配置,做为lib库,功能强大。数组
PHP不支持多进程,若是须要异步请求,非阻塞的方式,请选择fsockopen
。
常规的请求咱们使用file_get_contents
和curl
,除了功能外,下面作一个性能测试:服务器
$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的方式来请求接口数据。cookie
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
来请求,功能强大,使用方便,按需配置。