使用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页面运行时间的函数介绍
Jul 01 PHP
php 创建以UNIX时间戳命名的文件夹(示例代码)
Mar 08 PHP
微信支付开发教程(一)微信支付URL配置
May 28 PHP
PHP读取RSS(Feed)简单实例
Jun 12 PHP
Yii查询生成器(Query Builder)用法实例教程
Sep 04 PHP
php在数组中查找指定值的方法
Mar 17 PHP
PHP版微信公众平台红包API
Apr 02 PHP
PHP查找数值数组中不重复最大和最小的10个数的方法
Apr 20 PHP
Laravel 中获取上一篇和下一篇数据
Jul 27 PHP
thinkPHP利用ajax异步上传图片并显示、删除的示例
Sep 26 PHP
phpQuery采集网页实现代码实例
Apr 02 PHP
Laravel如何实现适合Api的异常处理响应格式
Jun 14 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实现文件安全下载
2006/10/09 PHP
那些年一起学习的PHP(二)
2012/03/21 PHP
php基于websocket搭建简易聊天室实践
2016/10/24 PHP
JavaScript 面向对象编程(2) 定义类
2010/05/18 Javascript
PHP 与 js的通信(via ajax,json)
2010/11/16 Javascript
javascript禁用键盘功能键让右击及其他键无效
2013/10/09 Javascript
浅析JavaScript中的delete运算符
2013/11/30 Javascript
一行命令搞定node.js 版本升级
2014/07/20 Javascript
js实现按Ctrl+Enter发送效果
2014/09/18 Javascript
jQuery与Ajax以及序列化
2016/02/01 Javascript
javascript实现简易计算器的代码
2016/05/31 Javascript
vue2实现可复用的轮播图carousel组件详解
2017/11/27 Javascript
vue+webpack模拟后台数据的示例代码
2018/07/26 Javascript
浅析Vue实例以及生命周期
2018/08/14 Javascript
浅谈JS的原型和继承
2019/05/08 Javascript
vuex + keep-alive实现tab标签页面缓存功能
2019/10/17 Javascript
[01:12]DOTA2次级职业联赛 - Newbee.Y 战队宣传片
2014/12/01 DOTA
python实现根据主机名字获得所有ip地址的方法
2015/06/28 Python
Python判断直线和矩形是否相交的方法
2015/07/14 Python
python 实现红包随机生成算法的简单实例
2017/01/04 Python
python中如何使用正则表达式的集合字符示例
2017/10/09 Python
使用matplotlib画散点图的方法
2018/05/25 Python
python实现对任意大小图片均匀切割的示例
2018/12/05 Python
python判断是空的实例分享
2020/07/06 Python
django filter过滤器实现显示某个类型指定字段不同值方式
2020/07/16 Python
5分钟让你掌握css3阴影、倒影、渐变小技巧(小编推荐)
2016/08/15 HTML / CSS
css3遮罩层镂空效果的多种实现方法
2020/05/11 HTML / CSS
美国转售二手商品的电子商务平台:BLINQ
2018/12/13 全球购物
美赞臣新加坡官方旗舰店:Enfagrow新加坡
2019/05/15 全球购物
如何写好升职自荐信
2014/01/06 职场文书
主题实践活动总结
2014/05/08 职场文书
疾病防治方案
2014/05/31 职场文书
病假证明模板
2015/06/19 职场文书
如何用JavaScript学习算法复杂度
2021/04/30 Javascript
关于Numpy之repeat、tile的用法总结
2021/06/02 Python
Redis Stream类型的使用详解
2021/11/11 Redis