PHP 支持 Daniel Stenberg 创建的 libcurl 库,能够连接通讯各种服务器、使用各种协议。libcurl 目前支持的协议有 http、https、ftp、gopher、telnet、dict、file、ldap。 libcurl 同时支持 HTTPS 证书、HTTP POST、HTTP PUT、 FTP 上传(也能通过 PHP 的 FTP 扩展完成)、HTTP 基于表单的上传、代理、cookies、用户名+密码的认证。
使用CURL的PHP扩展完成一个HTTP请求的发送一般有以下几个步骤:
1. 初始化连接句柄; curl_init();
2. 设置cURL选项; curl_setopt();
3. 执行并获取结果; curl_exec();
4. 释放cURL句柄。 curl_close();
// 1. 初始化
$ch = curl_init();
// 2. 设置选项,包括URL
curl_setopt($ch,CURLOPT_URL,"http://www.devdo.net");
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_HEADER,0);
// 3. 执行并获取HTML文档内容
$output = curl_exec($ch);
if($output === FALSE ){
echo "CURL Error:".curl_error($ch);
}
// 4. 释放curl句柄
curl_close($ch);
?>
上述代码中使用到了四个函数:
curl_init() 和 curl_close() 分别是初始化CURL连接和关闭CURL连接,都比较简单。
curl_exec() 执行CURL请求,如果没有错误发生,该函数的返回是对应URL返回的数据,以字符串表示满意;如果发生错误,该函数返回 FALSE。需要注意的是,判断输出是否为FALSE用的是全等号,这是为了区分返回空串和出错的情况。
CURL函数库里最重要的函数是curl_setopt(),它可以通过设定CURL函数库定义的选项来定制HTTP请求。上述代码片段中使用了三个重要的选项:
定义:curl_getinfo
— 获取一个cURL连接资源句柄的信息。获取最后一次传输的相关信息。
语法:mixed curl_getinfo ( resource $ch [, int $opt = 0 ] );
参数
ch
curl_init() 返回的 cURL
opt
参数可能是以下常量之一:
curl_exec($ch);
$url = curl_getinfo($ch,CURLINFO_EFFECTIVE_URL);
$total_time= curl_getinfo($ch,CURLINFO_TOTAL_TIME);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo '获取 '.$url.' ,耗时'.$total_time.'秒,HTTP状态码:'.$status;
返回值:
如果 opt 被设置,以字符串形式返回它的值。否则,返回返回一个包含下列元素的关联数组(它们分别对应于 opt):
curl_exec($ch);
$info = curl_getinfo($sh);
echo ' 获取 '.$info['url'].'耗时'.$info['total_time'].'秒,HTTP状态码:'.$info['http_code'];
上述代码中curl_getinfo返回的是一个关联数组,包含以下数据:
注意:
curl_getinfo()函数还有一个可选择参数$opt
,通过这个参数可以设置一些常量,对应到上术这个字段,如果设置了第二个参数,那么返回的只有指定的信息。例如:设置$opt
为CURLINFO_TOTAL_TIME
,则curl_getinfo()
函数只返回total_time
,即总传输消耗的时间,在只需要关注某些传输信息时,设置$opt参数很有意义。
//1、初始化cURL
$ch= curl_init();
//2、设置抓取的url
curl_setopt($ch, CURLOPT_URL, 'http://www.baidu.com');
//3、设置头文件的信息作为数据流输出(false为不输出)
curl_setopt($ch, CURLOPT_HEADER, false);
//4、设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//5、执行命令
$data = curl_exec($ch);
//6、关闭URL请求
curl_close($ch);
//7、显示获得的数据
print_r($data);
注意:
1、如果是https协议,添加代码如下:
//HTTPS协议添加下面一行代码:
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
1、test.php代码
header("content-type:text/html;charset=utf-8");
$url = "http://127.0.0.1/test/get_data/get_data.php?name=laowang&age=16&sex=man";
$ch= curl_init(); // 启动一个CURL会话
curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
curl_setopt($ch, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
$tmpInfo = curl_exec($ch); // 执行操作
curl_close($ch); // 关闭CURL会话
echo $tmpInfo; // 输出返回的数据
?>
2、get_data.php代码
$data['name'] = $_GET['name'];
$data['age'] = $_GET['age'];
$data['sex'] = $_GET['sex'];
if(empty($data)){
echo 'fail';
}else{
file_put_contents('wd.txt',$data);
echo 'success';
}
?>
注意:
返回值为success
则传值成功,返回fail
则失败。
1、test.php代码
header("content-type:text/html;charset=utf-8");
$url = "http://127.0.0.1/test/get_data/get_data.php";
$data = array('name'=>'laozhang','age'=>18,'sex'=>'woman');
$ch= curl_init(); // 启动一个CURL会话
curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
curl_setopt($ch, CURLOPT_POST, 1); // 发送一个常规的Post请求
if ($data != ''){
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
}
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
curl_setopt($ch, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
$tmpInfo = curl_exec($ch); // 执行操作
curl_close($ch); // 关闭CURL会话
echo $tmpInfo; // 返回数据
?>
2、get_data.php代码
$data['name'] = $_POST['name'];
$data['age'] = $_POST['age'];
$data['sex'] = $_POST['sex'];
if(empty($data)){
echo 'fail';
}else{
file_put_contents('./wd.txt',$data);
echo 'success';
}
?>
3、注意:有时候需要传递json格式的数据,接收数据的方式就要改变了
1、test.php代码修改
$data = json_encode(array('name'=>'隔壁老王','age'=>18,'sex'=>'女'),JSON_UNESCAPED_UNICODE);
......
//设置http的请求头
$header[] = "Content-Type:application/json;charset=utf-8";//成功
curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
2、get_data代码修改
$postData = file_get_contents('php://input');
$data = json_decode($postData,true);
if(empty($data)){
echo 'fail';
}else{
file_put_contents('wd.txt',$data);
echo 'success';
}
?>
4、test.php把GET请求和POST请求封装成方法
function http($url, $data='', $method='GET'){
$ch = curl_init(); // 启动一个CURL会话
curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
if($method=='POST'){
curl_setopt($ch, CURLOPT_POST, 1); // 发送一个常规的Post请求
if ($data != ''){
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
}
}
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
curl_setopt($ch, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
$tmpInfo = curl_exec($ch); // 执行操作
curl_close($ch); // 关闭CURL会话
return $tmpInfo; // 返回数据
}
?>
该段代码摘自《PHP中使用CURL模拟发送GET,POST,PUT,DELETE请求》
/*
* $url URL路径
* $method 传递参数的方法:get、post、put、delete
* $params 参数
* $auth 登录认证:账号和密码
*/
function curl($url,$method,$params,$auth=null){
//1、判断$url,$method,$params是否为空
if(empty($url) || empty($method) || empty($params)){
return '参数不能为空!';
}
//1、初始化CURL句柄
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);//设置请求的URL
#curl_setopt($curl, CURLOPT_HEADER, false);// 不要http header 加快效率
curl_setopt($curl, CURLOPT_RETURNTRANSFER,1); //设为TRUE把curl_exec()结果转化为字串,而不是直接输出
//2、SSL验证
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求时要设置为false 不验证证书和hosts FALSE 禁止 cURL 验证对等证书(peer's certificate), 自cURL 7.10开始默认为 TRUE。从 cURL 7.10开始默认绑定安装。
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);//检查服务器SSL证书中是否存在一个公用名(common name)。
//传送数据时,有的需要指定数据格式-下面是json格式,utf-8格式
$header[] = "Content-Type:application/json;charset=utf-8";
if(!empty($header)){
curl_setopt ( $curl, CURLOPT_HTTPHEADER, $header );//设置 HTTP 头字段的数组。格式: array('Content-type: text/plain', 'Content-length: 100')
}
//3、请求时间
$timeout = 30;
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);//设置连接等待时间
//4、不同请求方法的数据提交
switch ($method){
case "GET" :
curl_setopt($curl, CURLOPT_HTTPGET, true);//TRUE 时会设置 HTTP 的 method 为 GET,由于默认是 GET,所以只有 method 被修改时才需要这个选项。
break;
case "POST":
if(is_array($params)){
$params = json_encode($params,320);
}
#curl_setopt($curl, CURLOPT_POST,true);//TRUE 时会发送 POST 请求,类型为:application/x-www-form-urlencoded,是 HTML 表单提交时最常见的一种。
#curl_setopt($curl, CURLOPT_NOBODY, true);//TRUE 时将不输出 BODY 部分。同时 Mehtod 变成了 HEAD。修改为 FALSE 时不会变成 GET。
// curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");//HTTP 请求时,使用自定义的 Method 来代替"GET"或"HEAD"。对 "DELETE" 或者其他更隐蔽的 HTTP 请求有用。 有效值如 "GET","POST","CONNECT"等等;
//设置提交的信息
// curl_setopt($curl, CURLOPT_POSTFIELDS,$params);//全部数据使用HTTP协议中的 "POST" 操作来发送。
//设置请求方式是post方式
curl_setopt($curl,CURLOPT_POST,true);
//设置post请求提交的表单信息
curl_setopt($curl,CURLOPT_POSTFIELDS,$params);
break;
case "PUT" :
curl_setopt ($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_POSTFIELDS,json_encode($params,320));
break;
case "DELETE":
curl_setopt ($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($curl, CURLOPT_POSTFIELDS,$params);
break;
default:
echo '方法名不能为空!';
break;
}
//5、传递一个连接中需要的用户名和密码,格式为:"[username]:[password]"。
if (!empty($auth) && isset($auth['username']) && isset($auth['password'])) {
curl_setopt($curl, CURLOPT_USERPWD, "{$auth['username']}:{$auth['password']}");
}
//执行预定义的CURL
$output = curl_exec($curl);
//获取http返回值,最后一个收到的HTTP代码
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if($output === FALSE ){
echo "CURL Error:".curl_error($curl);
}else{
if($status === 200){
//如果返回值是json格式,就需要转换格式
// $output = json_decode($output,true);
}else{
$output = 'fail:请咨询管理员';
}
}
//关闭cURL会话
curl_close($curl);
return $output;
}
$arr = array('name'=>'wangdi');
var_dump(curl('http://127.0.0.1/test/get_data/get_data.php','POST',$arr));