使用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 相关文章推荐
第八节 访问方式 [8]
Oct 09 PHP
php错误、异常处理机制(补充)
May 07 PHP
php加水印的代码(支持半透明透明打水印,支持png透明背景)
Jan 17 PHP
PHP获取当前url的具体方法全面解析
Nov 26 PHP
跟我学Laravel之安装Laravel
Oct 15 PHP
PHP网络操作函数汇总
May 18 PHP
PHP技术开发微信公众平台
Jul 22 PHP
PHP文件上传问题汇总(文件大小检测、大文件上传处理)
Dec 24 PHP
Laravel 5.1 on SAE环境开发教程【附项目demo源码】
Oct 09 PHP
Discuz论坛密码与密保加密规则
Dec 19 PHP
PHP实现分布式memcache设置web集群session同步的方法
Apr 10 PHP
php微信开发之谷歌测距
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
jQuery+Ajax+PHP“喜欢”评级功能实现代码
2015/10/08 PHP
PHP常用字符串操作函数实例总结(trim、nl2br、addcslashes、uudecode、md5等)
2016/01/09 PHP
PHP反射机制原理与用法详解
2017/02/15 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
javascript 特殊字符串
2009/02/25 Javascript
Jquery AutoComplete自动完成 的使用方法实例
2010/03/19 Javascript
javascript 内存回收机制理解
2011/01/17 Javascript
DOM节点深度克隆函数cloneNode()用法实例
2015/01/12 Javascript
jQuery延迟加载图片插件Lazy Load使用指南
2015/03/25 Javascript
AngularJS初始化静态模板详解
2016/01/14 Javascript
深入理解JQuery循环绑定事件
2016/06/02 Javascript
JS针对Array的各种操作汇总
2016/11/29 Javascript
node.js实现回调的方法示例
2017/03/01 Javascript
JS实现带动画的回到顶部效果
2017/12/28 Javascript
使用use注册Vue全局组件和全局指令的方法
2018/03/08 Javascript
详解各版本React路由的跳转的方法
2018/05/10 Javascript
React.js绑定this的5种方法(小结)
2018/06/05 Javascript
详解JavaScript添加给定的标签选项
2018/09/17 Javascript
JS+HTML5 canvas绘制验证码示例
2018/12/05 Javascript
vue使用recorder.js实现录音功能
2019/11/22 Javascript
在Django的URLconf中进行函数导入的方法
2015/07/18 Python
详解python的webrtc库实现语音端点检测
2017/05/31 Python
深入理解Python中的*重复运算符
2017/10/28 Python
Python数据类型中的“冒号“[::]——分片与步长操作示例
2018/01/24 Python
Python中最大递归深度值的探讨
2019/03/05 Python
PyQt5 窗口切换与自定义对话框的实例
2019/06/20 Python
python实现静态web服务器
2019/09/03 Python
python实现单张图像拼接与批量图片拼接
2020/03/23 Python
长青弘远的面试题
2012/06/09 面试题
市场营销专业个人求职信范文
2013/12/14 职场文书
户外宣传策划方案
2014/05/25 职场文书
民政工作个人总结
2015/02/28 职场文书
2015年信息技术教研组工作总结
2015/07/22 职场文书
村主任当选感言
2015/08/01 职场文书
3招让你摆脱即兴讲话冷场尴尬
2019/08/08 职场文书
Python内置数据结构列表与元组示例详解
2021/08/04 Python