【澳门威斯尼人平台登录】在PHP中实现使用Guzzle执行POST和GET请求_php实例_脚本之家

本文实例讲述了PHP使用stream_context_create()模拟POST/GET请求的方法。分享给大家供大家参考,具体如下:

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

使用php可以模拟 post 和 get 传送数据到别的网页或站点

本文实例讲述了PHP实现支持GET,POST,Multipart/form-data的HTTP请求类及其应用,分享给大家供大家参考。具体如下:

以往在项目中要用到第三方接口时会用到封装好的curl执行请求,现在有了更好的解决方案——Guzzle。

有时候,我们需要在服务器端模拟 POST/GET 等请求,也就是在 PHP
程序中去实现模拟,改怎么做到呢?或者说,在 PHP
程序里,给你一个数组,如何将这个数组 POST/GET
到另外一个地址呢?当然,使用 CURL 很容易办到,那么如果不使用 CURL
库,又该怎么办呢?其实,在 PHP
里已经有相关的函数实现了,这个函数就是接下来要讲的
stream_context_create()。

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

$arr=array( 'user'=>'test', 'password'=>'');sock_get;sock_post; //fsocket模拟get提交function sock_get{ $query_str = http_build_query; $info = parse_url; $port = isset? $info['port'] : ; $query_str = empty?$query_str:$info["query"].'&'.$query_str; $fp = fsockopen($info["host"], $port, $errno, $errstr, ); if{ return FALSE; } //$head = "GET ".$info['path']."?".$info["query"]." HTTP/.\r\n"; $head = "GET ".$info['path']."?".$query_str." HTTP/.\r\n"; $head .= "Host: ".$info['host']."\r\n"; $head .= "\r\n"; $write = fputs; while{ $line = fread; echo $line; } fclose; return true;}//fsockopen模拟POSTfunction sock_post($url,$data=array{ $query = http_build_query; $info = parse_url; $fp = fsockopen($info["host"], , $errno, $errstr, ); $head = "POST ".$info['path']."?".$info["query"]." HTTP/.\r\n"; $head .= "Host: ".$info['host']."\r\n"; $head .= "Referer: http://".$info['host'].$info['path']."\r\n"; $head .= "Content-type: application/x-www-form-urlencoded\r\n"; $head .= "Content-Length: ".strlen."\r\n"; $head .= "\r\n"; $head .= trim; $write = fputs; while  { $line = fread; echo $line; }}

HttpRequest.class.php类文件如下:

下面是官方介绍:

直接 show you the code,这是最好的方法:

POST /目的程序url HTTP/1.1

以上内容是给大家分享的利用PHP fsockopen
模拟POST/GET传送数据的方法,希望大家能够喜欢,更多有关php
fsockopen知识请持续关注本站,谢谢。

_ip = isset? $config['ip'] : ''; $this->_host = isset? $config['host'] : ''; $this->_url = isset? $config['url'] : ''; $this->_port = isset? $config['port'] : ''; $this->_errno = isset? $config['errno'] : ''; $this->_errstr = isset? $config['errstr'] : ''; $this->_timeout = isset? $confg['timeout'] : 15; // 如没有设置ip,则用host代替 if{ $this->_ip = $this->_host; } } // 设置表单数据 public function setFormData{ $this->_formdata = $formdata; } // 设置文件数据 public function setFileData{ $this->_filedata = $filedata; } // 发送数据 public function send{ $type = strtolower; // 检查发送类型 if(!in_array($type, array('get','post','multipart'))){ return false; } // 检查连接 if{ switch{ case 'get': $out = $this->sendGet(); break; case 'post': $out = $this->sendPost(); break; case 'multipart': $out = $this->sendMultipart(); break; } // 空数据 if{ return false; } // 发送数据 fputs; // 读取返回数据 $response = ''; while($row = fread{ $response .= $row; } // 断开连接 $this->disconnect(); $pos = strpos($response, "\r\n\r\n"); $response = substr; return $response; }else{ return false; } } // 创建连接 private function connect(){ $this->_fp = fsockopen($this->_ip, $this->_port, $this->_errno, $this->_errstr, $this->_timeout); if{ return false; } return true; } // 断开连接 private function disconnect(){ if{ fclose; $this->_fp = null; } } // get 方式,处理发送的数据,不会处理文件数据 private function sendGet(){ // 检查是否空数据 if{ return false; } // 处理url $url = $this->_url.'?'.http_build_query; $out = "GET ".$url." http/1.1\r\n"; $out .= "host: ".$this->_host."\r\n"; $out .= "connection: close\r\n\r\n"; return $out; } // post 方式,处理发送的数据 private function sendPost(){ // 检查是否空数据 if(!$this->_formdata && !$this->_filedata){ return false; } // form data $data = $this->_formdata? $this->_formdata : array(); // file data if{ foreach($this->_filedata as $filedata){ if(file_exists{ $data[$filedata['name']] = file_get_contents; } } } if{ return false; } $data = http_build_query; $out = "POST ".$this->_url." http/1.1\r\n"; $out .= "host: ".$this->_host."\r\n"; $out .= "content-type: application/x-www-form-urlencoded\r\n"; $out .= "content-length: ".strlen."\r\n"; $out .= "connection: close\r\n\r\n"; $out .= $data; return $out; } // multipart 方式,处理发送的数据,发送文件推荐使用此方式 private function sendMultipart(){ // 检查是否空数据 if(!$this->_formdata && !$this->_filedata){ return false; } // 设置分割标识 srand*1000000); $boundary = '---------------------------'.substr,0,10); $data = '--'.$boundary."\r\n"; // form data $formdata = ''; foreach($this->_formdata as $key=>$val){ $formdata .= "content-disposition: form-data; name=\"".$key."\"\r\n"; $formdata .= "content-type: text/plain\r\n\r\n"; if{ $formdata .= json_encode."\r\n"; // 数组使用json encode后方便处理 }else{ $formdata .= rawurlencode."\r\n"; } $formdata .= '--'.$boundary."\r\n"; } // file data $filedata = ''; foreach($this->_filedata as $val){ if(file_exists{ $filedata .= "content-disposition: form-data; name=\"".$val['name']."\"; filename=\"".$val['filename']."\"\r\n"; $filedata .= "content-type: ".mime_content_type."\r\n\r\n"; $filedata .= implode('', file."\r\n"; $filedata .= '--'.$boundary."\r\n"; } } if(!$formdata && !$filedata){ return false; } $data .= $formdata.$filedata."--\r\n\r\n"; $out = "POST ".$this->_url." http/1.1\r\n"; $out .= "host: ".$this->_host."\r\n"; $out .= "content-type: multipart/form-data; boundary=".$boundary."\r\n"; $out .= "content-length: ".strlen."\r\n"; $out .= "connection: close\r\n\r\n"; $out .= $data; return $out; } } // class end ?>

Guzzle是一个PHP的HTTP客户端,用来轻而易举地发送请求,并集成到我们的WEB服务上。

$data = array( 'foo'=>'bar', 'baz'=>'boom', 'site'=>'localhost', 'name'=>'nowa magic'); $data = http_build_query; //$postdata = http_build_query;$options = array( 'http' => array( 'method' => 'POST', 'header' => 'Content-type:application/x-www-form-urlencoded', 'content' => $data //'timeout' => 60 * 60 // 超时时间;$url = "http://localhost/test2.php";$context = stream_context_create;$result = file_get_contents($url, false, $context);echo $result;

Accept: 接收信息格式

demo示例程序如下:

接口简单:构建查询语句、POST请求、分流上传下载大文件、使用HTTP
cookies、上传JSON数据等等。

的代码为:

Referer: url来路

 'demo.fdipzone.com', // 如空则用host代替 'host' => 'demo.fdipzone.com', 'port' => 80, 'errno' => '', 'errstr' => '', 'timeout' => 30, 'url' => '/getapi.php', //'url' => '/postapi.php', //'url' => '/multipart.php' ); $formdata = array( 'name' => 'fdipzone', 'gender' => 'man' ); $filedata = array( array( 'name' => 'photo', 'filename' => 'photo.jpg', 'path' => 'photo.jpg' ) ); $obj = new HttpRequest(); $obj->setConfig; $obj->setFormData; $obj->setFileData; $result = $obj->send; //$result = $obj->send; //$result = $obj->send; echo ''; print_r; echo '

发送同步或异步的请求均使用相同的接口。

$data = $_POST;echo '';print_r;echo '

Accept-Language: 接收语言

‘; ?>

使用PSR-7接口来请求、响应、分流,允许你使用其他兼容的PSR-7类库与Guzzle共同开发。

‘;

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

完整实例代码可以点击此处本站下载。

抽象了底层的HTTP传输,允许你改变环境以及其他的代码,如:对cURL与PHP的流或socket并非重度依赖,非阻塞事件循环。

Array( [foo] => bar [baz] => boom [site] => localhost [name] => nowa magic)

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

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

中间件系统允许你创建构成客户端行为。

  1. 以上程序用到了 http_build_query()
    函数,如果需要了解,可以参看前面一篇《PHP使用http_build_query()构造URL字符串的方法》。

  2. stream_context_create()
    是用来创建打开文件的上下文件选项的,比如用POST访问,使用代理,发送header等。就是
    创建一个流,再举一个例子吧:

    $context = stream_context_create(array( ‘http’ => array( ‘method’ => ‘POST’, ‘header’ => sprintf(“Authorization: Basic %s\r\n”, base64_encode($username.’:’.$password)). “Content-type: application/x-www-form-urlencoded\r\n”, ‘content’ => http_build_query(array), ‘timeout’ => 5, ), )); $ret = file_get_contents(”, false, $context);

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

安装

3.
stream_context_create创建的上下文选项即可用于流,也可用于文件系统。对于像
file_get_contents、file_put_contents、readfile直接使用文件名操作而没有文件句柄的函数来说更有用。stream_context_create增加header头只是一部份功能,还可以定义代理、超时等。这使得访问web的功能不弱于curl。

Host: 要发送到的主机地址

composer require guzzlehttp/guzzle //用composer安装最新guzzle,当前是6.3版
  1. stream_context_create()
    作用:创建并返回一个文本数据流并应用各种选项,可用于fopen等过程的超时设置、代理服务器、请求方式、头信息设置的特殊过程。

  2. stream_context_create 还能通过增加 timeout
    选项解决file_get_contents超时处理:

    $opts = array( ‘http’=>array( ‘method’=>”GET”, ‘timeout’=>60, ));//创建数据流上下文$context = stream_context_create;$html =file_get_contents(”, false, $context);//fopen输出文件指针处的所有剩余数据://fpassthru前使用

Content-Length: 发送数据的长度

GET请求示例

更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP运算与运算符用法总结》、《PHP网络编程技巧总结》、《PHP基本语法入门教程》、《php操作office文档技巧总结(包括word,excel,access,ppt)》、《php日期与时间用法总结》、《php面向对象程序设计入门教程》、《php字符串用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

Pragma: 本地是否存在缓存

$client = new GuzzleHttp\Client(); //初始化客户端$response = $client->get('http://httpbin.org/get', [ 'query' => [ //get查询字符串参数组 'a' => '参数a的值', 'b' => '参数b的值', ], 'timeout' => 3.14 //设置请求超时时间 ]); // 与上面一条等价// $response = $client->request('GET','http://httpbin.org/get', [// 'query' => [ // 'a' => '参数a的值',// 'b' => '参数b的值',// ],// 'timeout' => 3.14 // ]);$body = $response->getBody(); //获取响应体,对象$bodyStr = $body; //对象转字串,这就是请求返回的结果echo $bodyStr;

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

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

类似的请求方法还有:

Connection: 连接状态

$response = $client->get('http://httpbin.org/get');$response = $client->delete('http://httpbin.org/delete');$response = $client->head('http://httpbin.org/get');$response = $client->options('http://httpbin.org/get');$response = $client->patch('http://httpbin.org/patch');$response = $client->post('http://httpbin.org/post');$response = $client->put('http://httpbin.org/put');

username=fengdingbo&password=jb51.net //post发送的数据

POST请求示例

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

$client = new GuzzleHttp\Client();//普通表单`application/x-www-form-urlencoded`的POST请求$response = $client->post('http://httpbin.org/post', [ 'form_params' => [ //参数组 'a' => 'aaa', 'b' => 'bbb', 'nested_field' => [ //参数允许嵌套多层 'A' => 'AAA', 'B' => 'BBB', ] ],]); //包含文件上传的表单`multipart/form-data`的POST请求// $response = $client->post('http://httpbin.org/post', [// 'multipart' => [ //注意这个参数组的键名与前一个不同// [// 'name' => 'a', //字段名// 'contents' => 'aaa' //对应的值// ],// [// 'name' => 'upload_file_name', //文件字段名// 'contents' => fopen //文件资源// ],// ]// ]); $body = $response->getBody(); //获取响应体,对象 $bodyStr = $body; //对象转字串 echo $bodyStr;

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

以上便是Guzzle的POST和GET请求的基本介绍,相信很多时间掌握这两个语法方法已经能满足项目开发的需求了。当然这只是强大的Guzzle功能中很小的一部份,感兴趣的同学想深入了解的可以参考官方文档。希望大家多多支持脚本之家。

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

Guzzle6中文文档参考

在PHP中是如此简单呢!

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

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

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

代码如下

 * @link //www.jb51.net * @version 1.0 */ /** * Post Request * * @param string $url * @param array $data * @param string $referer * @return array */if ( ! function_exists{ function socket_post($url, $data, $referer='') { if { return; } $data = http_build_query; $url = parse_url; if ( ! isset || $url['scheme'] != 'http') { die('Error: Only HTTP request are supported !'); } $host = $url['host']; $path = isset ? $url['path'] : '/'; // open a socket connection on port 80 - timeout: 30 sec $fp = fsockopen($host, 80, $errno, $errstr, 30); if  { // send the request headers: $length = strlen; $POST = << 'error', 'error' => "$errstr ; } // close the socket connection: fclose; // split the result header from the content $result = explode; // return as structured array: return array( 'status' => 'ok', 'header' => isset ? $result[0] : '', 'content' => isset ? $result[1] : '' ); }} print_r(socket_post('//www.jb51.net/', array('name='=>'qiufeng','password'=>md5;/* e.g: socket_post('//www.jb51.net', array('name='=>'qiufeng','password'=>md5; *//* End of file socket_helper.php */

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

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

这个代码有两点要注意:

一是他是http的post 请求;

二是表单上传协议,

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

 $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; $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 . "rnrn"; // Open the connection $fp = fsockopen; // then just fputs; // reader while  { echo fgets; } fclose;

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

发表评论

电子邮件地址不会被公开。 必填项已用*标注