PHP socket 模拟POST 请求实例代码


Posted in PHP onJuly 18, 2016

我们用到最多的模拟POST请求几乎都是使用php curl来实现了,没考虑到PHP socket也可以实现,今天看到朋友写了一文章,下面我来给大家分享一下PHP socket模拟POST请求实例。

以前模拟post请求俺都用PHP curl扩展实现来着,没想过PHP socket也可以实现。最近翻了下相关资料才发现原来没有那么高深,只是以前一直没有完全理解post的原理和本质而已,其实就是发送给目的程序一个标志为post的协议串如下:

POST /目的程序url HTTP/1.1

Accept: 接收信息格式

Referer: url来路

Accept-Language: 接收语言

Content-Type: application/x-www-form-urlencoded

Cookie: 网站cookie,不用俺过多解释,对吧?

User-Agent: 用户代理,操作系统及版本、CPU 类型、浏览器及版本等信息

Host: 要发送到的主机地址

Content-Length: 发送数据的长度

Pragma: 本地是否存在缓存

Cache-Control: 是否需要网页缓存

Connection: 连接状态

username=fengdingbo&password=3water.com   //post发送的数据

我想大家对表单的post方法提交数据应该是最熟悉不过了,例如我们想把用户名和密码发送给某个页面的时候,填写好相应的input框,点击提交按钮,最后把这个表单发送到action程序的就是以上数据。知道了这一点我想就不难了

这时候我们只需要用php的socket打开一个端口,例如80端口,把以上信息利用这个端口发送给目的程序就行了。

我们如何在一个端口上建立一个socket通道呢?

在PHP中是如此简单呢!

官方给的原型:

resource fsockopen ( string $hostname [, int $port = -1 [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") ]]]] )

下边是人类的理解:

fsockopen(主机名称,端口号,错误号的&变量,错误提示的&变量,超时时间)
主机名称就是你需要发送数据的目的地;
端口号就是这个目的程序会在哪个端口等着你的数据;
错误号的&变量,这个是如果建立socket不成功的时候返回的错误编号;
错误提示的&变量,是错误的时候返回的错误提示信息;
超时时间,就是post数据之后如果对方没有回应信息,等待的最长时间。

如果不出意外(你正确的设置fsockopen()函数的参数)的话,一个socket通道现在已经打开了,我们下一步需要做的就是,通过这个打开的通道把post请求协议发给目的程序,这时候可以使用fwrite或者fputs函数中的任意一个,把post的请求格式发给fsockopen()打开的资源句柄,这时候一个伟大的socket模拟的post请求就诞生了。

 代码如下

<?php
/**
 * SOCKET扩展函数
 * @copyright (c) 2013
 * @author Qiufeng <fengdingbo@gmail.com>
 * @link https://3water.com
 * @version 1.0
 */
 
/**
 * Post Request
 *
 * @param string $url 
 * @param array $data
 * @param string $referer
 * @return array
 */
if ( ! function_exists('socket_post'))
{
 function socket_post($url, $data, $referer='')
 {
 if( ! is_array($data))
 {
 return;
 }
 
 $data = http_build_query($data);
 $url = parse_url($url);
 
 if ( ! isset($url['scheme']) || $url['scheme'] != 'http')
 {
 die('Error: Only HTTP request are supported !');
 }
 
 $host = $url['host'];
 $path = isset($url['path']) ? $url['path'] : '/';
 
 // open a socket connection on port 80 - timeout: 30 sec
 $fp = fsockopen($host, 80, $errno, $errstr, 30);
 
 if ($fp)
 {
 // send the request headers:
 $length = strlen($data);
 $POST = <<<HEADER
POST {$path} HTTP/1.1
Accept: text/plain, text/html
Referer: {$referer}
Accept-Language: zh-CN,zh;q=0.8
Content-Type: application/x-www-form-urlencodem 
Cookie: token=value; pub_cookietime=2592000; pub_sauth1=value; pub_sauth2=value
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17
Host: {$host}
Content-Length: {$length}
Pragma: no-cache
Cache-Control: no-cache
Connection: closern
{$data}
HEADER;
 fwrite($fp, $POST);
 $result = '';
 while(!feof($fp))
 {
 // receive the results of the request
 $result .= fread($fp, 512);
 }
 }
 else
 {
 return array(
  'status' => 'error',
  'error' => "$errstr ($errno)"
  );
 }
 
 // close the socket connection:
 fclose($fp);
 
 // split the result header from the content
 $result = explode("rnrn", $result, 2);
 
 // return as structured array:
 return array(
 'status' => 'ok',
 'header' => isset($result[0]) ? $result[0] : '',
 'content' => isset($result[1]) ? $result[1] : ''
 );
 }
}
 
print_r(socket_post('https://3water.com/', array('name='=>'qiufeng','password'=>md5('3water.com'))));
/* e.g: socket_post('https://3water.com', array('name='=>'qiufeng','password'=>md5('3water.com'))); */
/* End of file socket_helper.php */

实际上,当socket通道打开时,我们传的COOKIE是正确的话,(截图运行的php代码来自上边,运行后返回的网页出现了我的用户名,说明对方网站已经承认我已经登录了)咱就可以干N多事情,比如刷帖,刷回复等,你们懂的,对吧?

好了上面还不够有说服力我们来看一个php socket实现图片上传

这个代码有两点要注意:

一是他是http的post 请求;

二是表单上传协议,

下的请求 串适合任何语言.

代码如下 

<?php 
 
  $remote_server = "3water.com"; 
 
  $boundary = "---------------------".substr(md5(rand(0,32000)),0,10); 
   
  // Build the header 
  $header = "POST /api.php?action=twupload HTTP/1.0rn"; 
  $header .= "Host: {$remote_server}rn"; 
  $header .= "Content-type: multipart/form-data, boundary=$boundaryrn"; 
 
  /* 
  // attach post vars 
  foreach($_POST AS $index => $value){ 
   $data .="--$boundaryrn"; 
   $data .= "Content-Disposition: form-data; name="".$index.""rn"; 
   $data .= "rn".$value."rn"; 
   $data .="--$boundaryrn"; 
  } 
  */
  $file_name = "aaa.jpg"; 
  $content_type = "image/jpg"; 
 
  $data = ''; 
  // and attach the file 
  $data .= "--$boundaryrn"; 
 
  $content_file = file_get_contents('aaa.jpg'); 
  $data .="Content-Disposition: form-data; name="userfile"; filename="$file_name"rn"; 
  $data .= "Content-Type: $content_typernrn"; 
  $data .= "".$content_file."rn"; 
  $data .="--$boundary--rn"; 
 
  $header .= "Content-length: " . strlen($data) . "rnrn"; 
     // Open the connection 
 
 
  $fp = fsockopen($remote_server, 80); 
  // then just 
  fputs($fp, $header.$data); 
  // reader 
 
 while (!feof($fp)) { 
  echo fgets($fp, 128); 
 } 
 
fclose($fp);

希望本文对大家的 PHP程序设计有所帮助。

PHP 相关文章推荐
PHP初学者头疼问题总结
Oct 09 PHP
用PHP将数据导入到Foxmail
Oct 09 PHP
php 在文件指定行插入数据的代码
May 08 PHP
PHP文件读写操作之文件写入代码
Jan 13 PHP
解析dedecms空间迁移步骤详解
May 15 PHP
PHP分页详细讲解(有实例)
Oct 30 PHP
关于PHP的curl开启问题探讨
Apr 08 PHP
php通过ksort()函数给关联数组按照键排序的方法
Mar 18 PHP
如何在HTML 中嵌入 PHP 代码
May 13 PHP
PHP验证信用卡卡号是否正确函数
May 27 PHP
php实现图片上传并利用ImageMagick生成缩略图
Mar 14 PHP
PHP中in_array的隐式转换的解决方法
Mar 06 PHP
Yii2简单实现给表单添加验证码的方法
Jul 18 #PHP
yii2缓存Caching基本用法示例
Jul 18 #PHP
yii2.0实现创建简单widgets示例
Jul 18 #PHP
php cookie工作原理与实例详解
Jul 18 #PHP
Yii2针对指定url的生成及图片等的引入方法小结
Jul 18 #PHP
图文详解PHP环境搭建教程
Jul 16 #PHP
Yii调试查看执行SQL语句的方法
Jul 15 #PHP
You might like
NO3第三帝国留言簿制作过程
2006/10/09 PHP
php 常用字符串函数总结
2008/03/15 PHP
写出高质量的PHP程序
2012/02/04 PHP
php并发对MYSQL造成压力的解决方法
2013/02/21 PHP
PHP的mysqli_query参数MYSQLI_STORE_RESULT和MYSQLI_USE_RESULT的区别
2014/09/29 PHP
PHP添加文字水印或图片水印的水印类完整源代码与使用示例
2019/03/18 PHP
详解no input file specified 三种解决方法
2019/11/29 PHP
让getElementsByName适应IE和firefox的方法
2007/09/24 Javascript
javascript showModalDialog 多层模态窗口实现页面提交及刷新的代码
2009/11/28 Javascript
js正则表达式中test,exec,match方法的区别说明
2014/01/29 Javascript
php的文件上传入门教程(实例讲解)
2014/04/10 Javascript
浅谈jQuery 中的事件冒泡和阻止默认行为
2016/05/28 Javascript
jquery实现跳到底部,回到顶部效果的简单实例(类似锚)
2016/07/10 Javascript
javascript 判断页面访问方式电脑或者移动端
2016/09/19 Javascript
理解AngularJs篇:30分钟快速掌握AngularJs
2016/12/23 Javascript
js 将input框中的输入自动转化成半角大写(税号输入框)
2017/02/16 Javascript
浅谈Angular4实现热加载开发旅程
2017/09/08 Javascript
JavaScript深拷贝和浅拷贝概念与用法实例分析
2018/06/07 Javascript
js中call()和apply()改变指针问题的讲解
2019/01/17 Javascript
VuePress 静态网站生成方法步骤
2019/02/14 Javascript
Nautil 中使用双向数据绑定的实现
2019/10/02 Javascript
详解Python中的from..import绝对导入语句
2016/06/21 Python
Python3 socket同步通信简单示例
2017/06/07 Python
Python基于聚类算法实现密度聚类(DBSCAN)计算【测试可用】
2018/12/26 Python
python顺序执行多个py文件的方法
2019/06/29 Python
PyCharm Anaconda配置PyQt5开发环境及创建项目的教程详解
2020/03/24 Python
详解python爬取弹幕与数据分析
2020/11/14 Python
俄罗斯玩具、儿童用品、儿童服装和鞋子网上商店:MyToys.ru
2019/10/14 全球购物
介绍一下Ruby的多线程处理
2013/02/01 面试题
艺术系大学生毕业个人自我评价
2013/09/19 职场文书
物业管理员岗位职责范文
2013/11/25 职场文书
全国税务系统先进集体事迹材料
2014/05/19 职场文书
幼儿生日活动方案
2014/08/27 职场文书
法学专业毕业实习自我鉴定2014
2014/09/27 职场文书
Python制作一个随机抽奖小工具的实现
2021/07/07 Python
python之基数排序的实现
2021/07/26 Python