使用PHP Socket 编程模拟Http post和get请求


Posted in PHP onNovember 25, 2014

这里给大家分享一段使用PHP Socket 编程模拟Http post和get请求的代码,非常的实用,结尾部分我们再讨论下php模拟http请求的几种方法。

<?php /** 

 * 使用PHP Socket 编程模拟Http post和get请求 

 * @author koma 

 */ class Http{ 

    private $sp = "\r\n"; //这里必须要写成双引号     private $protocol = 'HTTP/1.1'; 

    private $requestLine = ""; 

    private $requestHeader = ""; 

    private $requestBody = ""; 

    private $requestInfo = ""; 

    private $fp = null; 

    private $urlinfo = null; 

    private $header = array(); 

    private $body = ""; 

    private $responseInfo = ""; 

    private static $http = null; //Http对象单例     

    private function __construct() {} 

    public static function create() { 

        if ( self::$http === null ) {  

            self::$http = new Http(); 

        } 

        return self::$http; 

    } 

    public function init($url) { 

        $this->parseurl($url); 

        $this->header['Host'] = $this->urlinfo['host']; 

        return $this; 

    } 

    public function get($header = array()) { 

        $this->header = array_merge($this->header, $header); 

        return $this->request('GET'); 

    } 

    public function post($header = array(), $body = array()) { 

        $this->header = array_merge($this->header, $header); 

        if ( !empty($body) ) { 

            $this->body = http_build_query($body); 

            $this->header['Content-Type'] = 'application/x-www-form-urlencoded'; 

            $this->header['Content-Length'] = strlen($this->body); 

        } 

        return $this->request('POST'); 

    } 

    private function request($method) { 

        $header = ""; 

        $this->requestLine = $method.' '.$this->urlinfo['path'].'?'.$this->urlinfo['query'].' '.$this->protocol; 

        foreach ( $this->header as $key => $value ) { 

            $header .= $header == "" ? $key.':'.$value : $this->sp.$key.':'.$value; 

        } 

        $this->requestHeader = $header.$this->sp.$this->sp; 

        $this->requestInfo = $this->requestLine.$this->sp.$this->requestHeader; 

        if ( $this->body != "" ) { 

            $this->requestInfo .= $this->body; 

        } 

        /* 

         * 注意:这里的fsockopen中的url参数形式为"www.xxx.com" 

         * 不能够带"http://"这种 

         */

        $port = isset($this->urlinfo['port']) ? isset($this->urlinfo['port']) : '80'; 

        $this->fp = fsockopen($this->urlinfo['host'], $port, $errno, $errstr); 

        if ( !$this->fp ) { 

            echo $errstr.'('.$errno.')'; 

            return false; 

        } 

        if ( fwrite($this->fp, $this->requestInfo) ) { 

            $str = ""; 

            while ( !feof($this->fp) ) { 

                $str .= fread($this->fp, 1024); 

            } 

            $this->responseInfo = $str; 

        } 

        fclose($this->fp); 

        return $this->responseInfo; 

    } 

    private function parseurl($url) { 

        $this->urlinfo = parse_url($url); 

    } 

} // $url = "http://news.163.com/14/1102/01/AA0PFA7Q00014AED.html"; 

$url = "http://localhost/httppro/post.php"; $http = Http::create()->init($url); /* 发送get请求  

echo $http->get(array( 

    'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36', 

)); 

*/

 /* 发送post请求 */ echo $http->post(array( 

        'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36', 

), array('username'=>'发一个中文', 'age'=>22));

php 模拟 http请求

方法一:利用php的socket编程来直接给接口发送数据来模拟post的操作。

建立两个文件post.php,getpost.php
post.php内容如下:

<?php

 $flag = 0;

 $params = '';

 $errno = '';

 $errstr = '';

 //要post的数据

$argv = array(

    'var1'=>'abc',

    'var2'=>'how are you , my friend??');

//构造要post的字符串

foreach ($argv as $key=>$value) {

    if ($flag!=0) {

        $params .= "&";

        $flag = 1;

    }

    $params.= $key."="; $params.= urlencode($value);

    $flag = 1;

    }

    $length = strlen($params);

     //创建socket连接

    $fp = fsockopen("localhost",81,$errno,$errstr,10) or exit($errstr."--->".$errno);

    //构造post请求的头

    $header  = "POST /flandy/getpost.php HTTP/1.1\r\n";

    $header .= "Host:127.0.0.1\r\n";

    $header .= "Referer:/flandy/post.php\r\n";

    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";

    $header .= "Content-Length: ".$length."\r\n";

    $header .= "Connection: Close\r\n\r\n";

    //添加post的字符串

    $header .= $params."\r\n";

   
    //发送post的数据

    fputs($fp,$header);

    $inheader = 1;

    while (!feof($fp)) {

        $line = fgets($fp,1024); //去除请求包的头只显示页面的返回数据

        if ($inheader && ($line == "\n" || $line == "\r\n")) {

             $inheader = 0;

        }

        if ($inheader == 0) {

          echo $line;

        }

    }
fclose($fp);

?>

getpost.php的内容如下

<?php

echo "this is the data posted";

echo "<pre>";

print_r($_REQUEST);

echo "</pre>";

?>

结果输出:

this is the data postedArray

(

[var1] => abc

[var2] => how are you , my friend??

)

以上代码在本机81端口下已经通过测试。

方法二:

使用PHP的curl扩展或HttpClient.class.php类,这两个非常类似,下面简单的列出curl的实现代码。
两个文件post2.php和getpost2.php
post2.php的内容如下:

<?php

$psecode = 'NDE005';

$website = 'www.baidu.com';

$amt = 1;

$pwd = 123456;

$ch = curl_init();

$curl_url = "http://localhost:81/flandy/getpost2.php?web=" . $website .

"&pwd=" . $pwd . "&action=check&pseid=" . $psecode .

"&amt=" . $amt;

curl_setopt($ch, CURLOPT_URL, $curl_url);

curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不直接输出,返回到变量

$curl_result = curl_exec($ch);

$result = explode(',', $curl_result);

curl_close($ch);

print_r($result);

?>

getpost2.php的内容如下:

<?php

echo "returndata<br>";

echo "<pre>";

print_r($_REQUEST);

echo "</pre>";

?>

结果输出:

Array ( [0] => returndataArray

(

[web] => 'wwwbaiducom'

[pwd] => 123456

[action] => check

[pseid] => 'NDE005'

[amt] => 1

)

)

方法三:

这个要借助第三方类库HttpClient可以到这里下载:http://scripts.incutio.com/httpclient/

<?php

require_once 'HttpClient.class.php';

$params = array('web' => 'www.baidu.com',

'pwd' => '123456',

'action' => 'check',

'pseid' => 'NDE005',

'amt' => 1);

$pageContents = HttpClient::quickPost('http://localhost:81/flandy/getpost3.php', $params);

$result = explode(',', $pageContents);

print_r($result);

?>
PHP 相关文章推荐
用PHP和MySQL保存和输出图片
Oct 09 PHP
PHP个人网站架设连环讲(三)
Oct 09 PHP
PHP+MySQL投票系统的设计和实现分享
Sep 23 PHP
解析crontab php自动运行的方法
Jun 24 PHP
对淘宝URL中ID提取的PHP代码
Sep 01 PHP
jquery获取多个checkbox的值异步提交给php的方法
Jun 24 PHP
php实现基于openssl的加密解密方法
Sep 30 PHP
理清PHP在Linxu下执行时的文件权限方法
Jun 07 PHP
php魔法函数与魔法常量使用介绍
Jul 23 PHP
PHP实现读取文件夹及批量重命名文件操作示例
Apr 15 PHP
PHP连接SQL Server的方法分析【基于thinkPHP5.1框架】
May 06 PHP
php swoole多进程/多线程用法示例【基于php7nts版】
Aug 12 PHP
PHP实现无限极分类图文教程
Nov 25 #PHP
php获取指定日期之间的各个周和月的起止时间
Nov 24 #PHP
Thinkphp搭建包括JS多语言的多语言项目实现方法
Nov 24 #PHP
thinkphp判断访客为手机端或PC端的方法
Nov 24 #PHP
ThinkPHP公共配置文件与各自项目中配置文件组合的方法
Nov 24 #PHP
php使用str_replace实现输入框回车替换br的方法
Nov 24 #PHP
thinkphp循环结构用法实例
Nov 24 #PHP
You might like
php序列化函数serialize() 和 unserialize() 与原生函数对比
2015/05/08 PHP
PHP请求远程地址设置超时时间的解决方法
2016/10/29 PHP
laravel5使用freetds连接sql server的方法
2018/12/07 PHP
修改Laravel自带的认证系统的User类的命名空间的步骤
2019/10/15 PHP
不用AJAX和IFRAME,说说真正意义上的ASP+JS无刷新技术
2008/09/25 Javascript
js电信网通双线自动选择技巧
2008/11/18 Javascript
JavaScript入门教程(9) Document文档对象
2009/01/31 Javascript
基于jquery的checkbox下拉框插件代码
2010/06/25 Javascript
javascript函数以及基础写法100多条实用整理
2013/01/13 Javascript
JS中如何判断传过来的JSON数据中是否存在某字段
2014/08/18 Javascript
js实现百度联盟中一款不错的图片切换效果完整实例
2015/03/04 Javascript
JavaScript Sort 的一个错误用法示例
2015/03/20 Javascript
js微信分享API
2020/10/11 Javascript
JavaScript中return用法示例
2016/11/29 Javascript
js querySelector() 使用方法
2016/12/21 Javascript
JS打开摄像头并截图上传示例
2017/02/18 Javascript
vue element-ui table组件动态生成表头和数据并修改单元格格式 父子组件通信
2019/08/15 Javascript
Vue中图片Src使用变量的方法
2019/10/30 Javascript
Swift中的协议(protocol)学习教程
2016/07/08 Python
使用python实现knn算法
2017/12/20 Python
Python使用内置函数setattr设置对象的属性值
2020/10/16 Python
Python 转移文件至云对象存储的方法
2021/02/07 Python
解决CSS3的opacity属性带来的层叠顺序问题
2016/05/09 HTML / CSS
Tenstickers法国:墙贴和装饰贴纸
2019/08/26 全球购物
二年级体育教学反思
2014/01/15 职场文书
自荐信如何制作?
2014/02/21 职场文书
学习教师敬业奉献模范事迹材料思想汇报
2014/09/19 职场文书
发展党员工作情况汇报
2014/10/28 职场文书
2014年租房协议书范本
2014/10/30 职场文书
幼儿园教师节感谢信
2015/01/23 职场文书
公积金贷款承诺书
2015/04/30 职场文书
2015年电信员工工作总结
2015/05/26 职场文书
党风廉政建设心得体会
2019/05/21 职场文书
公司财务制度:成本管理控制制度模板
2019/11/19 职场文书
Mysql 如何实现多张无关联表查询数据并分页
2021/06/05 MySQL
FP-growth算法发现频繁项集——构建FP树
2021/06/24 Python