在PHP项目开发中,经常会遇到有时候需要采集信息简单的页面直接使用file_get_contents()函数就能实现了。复杂点的比如采集cnzz统计数据或者远程登录(数据库在别人服务器上,你把用户提交的数据传输到它人的服务器,远程接口给你返回是否正确的信息)等等。这种比较复杂点的就需要用到PHP中的curl扩展。curl的扩展安装我在文章PHP CURL使用详解中有提到。

下面我介绍下在PHP中我们使用curl模拟POST登录

示例主要有两个文件:post.phphandleLogin.php

post.php

<?php 
  $url = 'http://z.vilay.com/handleLogin.php';
  $post_data = array('username'=>'vilay','password'=>'123456');
  $ch = curl_init();
  curl_setopt($ch,CURLOPT_URL,$url);
  curl_setopt($ch,CURLOPT_POST,1);
  curl_setopt($ch,CURLOPT_HEADER,0);
  curl_setopt($ch,CURLOPT_POSTFIELDS,$post_data);
  curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
  $result = curl_exec($ch);
  curl_close($ch);
  var_dump($result);

handleLogin.php

<?php 
if ($_POST['username'] == 'vilay' && $_POST['password'] == '123456') {
	echo 'success';
} else {
	echo 'failed';
}

结果输出:

string(7) "success"

很显然,我们登录成功了。

下面我用示例演示下 curl_setopt($ch,CURLOPT_HEADER,0);CURLOPT_HEADERcurl_setopt($ch,CURLOPT_RETURNTRANSFER,1);CURLOPT_RETURNTRANSFER不同设置的意义。 其它参数可以参考:PHP CURL使用详解

handleLogin.php不变

参数含义:

CURLOPT_HEADER : (值为布尔型)启用时会将头文件的信息作为数据流输出。
CURLOPT_RETURNTRANSFER :(值为布尔型) 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。

设置CURLOPT_HEADER为1示例:

<?php 
$url = 'http://z.vilay.com/handleLogin.php';
$post_data = array('username'=>'vilay','password'=>'123456');
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_HEADER,1);//值有改变
curl_setopt($ch,CURLOPT_POSTFIELDS,$post_data);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$result = curl_exec($ch);
curl_close($ch);
echo "<pre>";
var_dump($result);

结果输出:

string(251) "HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Mon, 04 Jan 2016 13:22:06 GMT
Server: Apache/2.4.12 (Win64) PHP/5.6.9 OpenSSL/1.0.1m
X-Distributed-by: AHC
X-Powered-By: PHP/5.6.9
Content-Length: 7
Content-Type: text/html; charset=UTF-8

success"

CURLOPT_HEADER值设为真头文件信息会以数据流的形式输出。

设置CURLOPT_RETURNTRANSFER为0示例:

<?php 
$url = 'http://z.vilay.com/handleLogin.php';
$post_data = array('username'=>'vilay','password'=>'123456');
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_POSTFIELDS,$post_data);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,0);//值有改变
$result = curl_exec($ch);
curl_close($ch);
echo "<pre>";
var_dump($result);

结果输出:

success
bool(true)

从代码我们可以看出,我们除了有在最后打印$result,在其他地方并没有人为输出东西。因此可以看出success是curl输出的,第二行布尔值才是我们用var_dump()函数打印输出的。由此可以看出__CURLOPT_RETURNTRANSFER值为真时,curl_exec()函数获取的信息以文件流形式返回,当值为假时,直接输出在页面上__。

我们再看一个示例,在这个示例中我们不仅仅改变了CURLOPT_RETURNTRANSFER的值,Post数据中的password也改变了,换句话说密码是错误的:

<?php 
$url = 'http://z.vilay.com/handleLogin.php';
$post_data = array('username'=>'vilay','password'=>'12345678'); //password值有改变
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_POSTFIELDS,$post_data);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,0);//值有改变
$result = curl_exec($ch);
curl_close($ch);
echo "<pre>";
var_dump($result);

结果输出:

failed
bool(true)

由两个示例可以看出,一旦CURLOPT_RETURNTRANSFER值为假,返回结果不能作为判断依据,在登录这个情景中无论密码对与错$result都是真,无法作为判断依据,因此我们在模拟登录中CURLOPT_RETURNTRANSFER__必须__设为真。