php中模拟POST提交数据两种方法
下面总结了在php中有两种可以模仿用户进入登录或post数据的实现方法,对大家很有用,有需要的朋友可参考一下.
通过curl函数:PHP中的CURL函数库(Client URL Library Function)
curl_close — 关闭一个curl会话
curl_copy_handle — 拷贝一个curl连接资源的所有内容和参数
curl_errno — 返回一个包含当前会话错误信息的数字编号
curl_error — 返回一个包含当前会话错误信息的字符串
curl_exec — 执行一个curl会话
curl_getinfo — 获取一个curl连接资源句柄的信息
curl_init — 初始化一个curl会话
curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄资源
curl_multi_close — 关闭一个批处理句柄资源
curl_multi_exec — 解析一个curl批处理句柄
curl_multi_getcontent — 返回获取的输出的文本流
curl_multi_info_read — 获取当前解析的curl的相关传输信息
curl_multi_init — 初始化一个curl批处理句柄资源
curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源
curl_multi_select — Get all the sockets associated with the cURL extension, which can then be "selected"
curl_setopt_array — 以数组的形式为一个curl设置会话参数
curl_setopt — 为一个curl设置会话参数
curl_version — 获取curl相关的版本信息
curl_init()函数的作用初始化一个curl会话,curl_init()函数唯一的一个参数是可选的,表示一个url地址。
curl_exec()函数的作用是执行一个curl会话,唯一的参数是curl_init()函数返回的句柄。
curl_close()函数的作用是关闭一个curl会话,唯一的参数是curl_init()函数返回的句柄。
例,代码如下:
- $post_data = array();
- $post_data['clientname'] = "test08";
- $post_data['clientpasswd'] = "test08";
- $post_data['submit'] = "submit";
- $url='http://xxx.xxx.xxx.xx/xx/xxx/top.php';
- $o="";
- foreach ($post_data as $k=>$v)
- {
- $o.= "$k=".urlencode($v)."&";
- }//开源代码phpfensi.com
- $post_data=substr($o,0,-1);
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_HEADER, 0);
- curl_setopt($ch, CURLOPT_URL,$url);
- //为了支持cookie
- curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
- curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
- $result = curl_exec($ch);
模仿用户登录,模拟登录到sina,我们要抓取数据,可能是登录以后的内容,这个时候我们就要用到curl的模拟登录功能了,代码如下:
- function checklogin( $user, $password )
- {
- if ( emptyempty( $user ) || emptyempty( $password ) )
- {
- return 0;
- }
- $ch = curl_init( );
- curl_setopt( $ch, CURLOPT_REFERER, "http://mail.sina.com.cn/index.html" );
- curl_setopt( $ch, CURLOPT_HEADER, true );
- curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
- curl_setopt( $ch, CURLOPT_USERAGENT, USERAGENT );
- curl_setopt( $ch, CURLOPT_COOKIEJAR, COOKIEJAR );
- curl_setopt( $ch, CURLOPT_TIMEOUT, TIMEOUT );
- curl_setopt( $ch, CURLOPT_URL, "http://mail.sina.com.cn/cgi-bin/login.cgi" );
- curl_setopt( $ch, CURLOPT_POST, true );
- curl_setopt( $ch, CURLOPT_POSTFIELDS, "&logintype=uid&u=".urlencode( $user )."&psw=".$password );
- $contents = curl_exec( $ch );
- curl_close( $ch );
- if ( !preg_match( "/Location: (.*)\/cgi\/index\.php\?check_time=(.*)n/", $contents, $matches ) )//开源代码phpfensi.com
- {
- return 0;
- }else{
- return 1;
- }
- }
- define( "USERAGENT", $_SERVER['HTTP_USER_AGENT'] );
- define( "COOKIEJAR", tempnam( "/tmp", "cookie" ) );
- define( "TIMEOUT", 500 );
- echo checklogin("zhangying215","xtaj227");
2.通过fsockopen
.PHP fsockopen函数说明:
Open Internet or Unix domain socket connection(打开套接字链接)
Initiates a socket connection to the resource specified by target .
fsockopen() returns a file pointer which may be used together with the other file functions (such as fgets() , fgetss() , fwrite() , fclose() , and feof() ).就是返回一个文件句柄
开启PHP fsockopen这个函数,PHP fsockopen需要 PHP.ini 中 allow_url_fopen 选项开启,代码如下:
- $URL=‘http://xxx.xxx.xxx.xx/xx/xxx/top.php';
- $post_data['clientname'] = "test08";
- $post_data['clientpasswd'] = "test08";
- $post_data['submit'] = "ログイン";
- $referrer="";
- // parsing the given URL
- $URL_Info=parse_url($URL);
- // Building referrer
- if($referrer=="") // if not given use this script as referrer
- $referrer=$_SERVER["SCRIPT_URI"];
- // making string from $data
- foreach($post_data as $key=>$value)
- $values[]="$key=".urlencode($value);
- $data_string=implode("&",$values);
- // Find out which port is needed - if not given use standard (=80)
- if(!isset($URL_Info["port"]))
- $URL_Info["port"]=80;
- // building POST-request:
- $request.="POST ".$URL_Info["path"]." HTTP/1.1n";
- $request.="Host: ".$URL_Info["host"]."n";
- $request.="Referer: $referrern";
- $request.="Content-type: application/x-www-form-urlencodedn";
- $request.="Content-length: ".strlen($data_string)."n";
- $request.="Connection: closen";
- $request.="n";
- $request.=$data_string."n";
- $fp = fsockopen($URL_Info["host"],$URL_Info["port"]);
- fputs($fp, $request);
- while(!feof($fp)) {
- $result .= fgets($fp, 128);
- }
- fclose($fp);
如果出现:Warning: fsockopen() has been disabled for security reasons in D:…cos-html-cachecos-html-cache.php on line 35
换了其他版本的cos-html-cache,还是不行,后来找到下面的方法,结果不行,因为函数都被禁用了,大家试下,很少有我这样的情况的,用其他替代函数.
一、如何禁用fsockopen()
下面是两种常用的禁用fsockopen的方法.
1、修改php.ini,将 disable_functions = 后加入 fsockopen
2、修改php.ini,将 allow_url_fopen = On 改为 allow_url_fopen = Off
二、如何解决fsockopen函数被禁用
1、如果服务器没有同时禁用pfsockopen,那么直接将fsockopen函数替换为pfsockopen.
具体操作:搜索程序中的字符串fsockopen替换为 pfsockopen示例如下.
修改前:$fp = fsockopen($host,80,$errno,$errstr,30);
修改后:$fp = pfsockopen($host,80,$errno, $errstr,30);