PHP - 模拟HTTP请求, stream_context_create 和 fopen 和 fsockopen
一、fsocketopen,使用这个的过程看起来更像别的语言的socket编程
public function send($request) { /* 请求数据 */
$post_data = $request;
$lenght = strlen($post_data);
$headers = "{$this->type} /{$this->url} HTTP/1.1\r\n";
$headers .= "Accept: * /*\r\n";
$headers .= "Content-Type: application/x-www-form-urlencoded\r\n";
$headers .= "User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6; CIBA; .NET CLR 4.0.20506)\r\n"; //如果存在$session
if($session != "" )
$headers .= "Cookie:JSESSIONID={$this->session}\r\n"; $headers .= "Host: {$this->host}:{$this->port}\r\n";
$headers .= "Content-Length: {$lenght}\r\n";
$headers .= "Connection: Close\r\n\r\n";
$headers .= $post_data;
if( $fp = fsockopen( $this->host, $this->port, $errno, $errstr, 100) ) {
fwrite($fp, $headers);
$header = fread($fp, 1024);
$content = fread($fp, 1024);
$content .= fread($fp, 1024);
$content .= fread($fp, 1024);
$content .= fread($fp, 1024);
fclose($fp);
}//end of if
如上图所示,只要链接到相应的主机和端口,然后我们就已经tcp上了主机,然后写工作在tcp之上的http协议头部,就$header里面的内容,当然有很多是不必要的 ,只用写Content_Length,和Content_Type;
关于TCP的细节还是参照RFC文档,头部换行再空一行之后就是内容去,也就是$requst,响应的协调好两边传输的内容比如用json来,应该来说已经比较方便了,要不最多自己解析自己写的字符串也可以。这样写好头部之后我们的请求就可以被apache或者ngix之类的服务器识别了然后调到相应的php 文件。非常容易.
二,fopen函数。
这个貌似我只在打开本地文件的时候用过了,在php manual里面是这样描述的 fopen — Opens file or URL。显然我们可以用过url来标识定位远程的PHP文件,当我们定位到的时候同样取得请求会被apache获取然后被php引擎执行,然后返回结果。但是我还是觉得这个函数好神奇。有一点要注意的就是:url前面必须写上http://
这样之后还不够,还要依赖另外一个函数steam_content_create() ,实例代码如下:
<?php
$opts = array ('http' => array (
'method' => 'POST',
'header' => 'Content-type: application/json',
'content' => $request
));
$context = stream_context_create($opts);
if ($fp = fopen($this->url, 'r', false, $context)) {
$response = '';
while($row = fgets($fp)) {
$response.= trim($row)."\n";
}
$this->debug && $this->debug.='***** Server response *****'."\n".$response.'***** End of server response *****'."\n";
$response = json_decode($response,true);
} else {
throw new Exception('Unable to connect to '.$this->url);
}
最后也是最重要的一点就是我在解析RPC的时候遇到了一个巨大的坑。
redirect这种东西经常遇到,例如你访问网站默认访问index.html index.php 等等文件。或者你会在php里面给他个header('location:***')。一开始的时候我把服务器文件放在一个叫rpc的目录下面,然后客户端的url我就写的http://***.***.com/rpc 这下就悲剧了,各种情况都说明了我已经定位到那个文件的,而且文件的代码已经执行了,但是永远不是POST过去的,而且携带的数据也全部丢失了。搞得我非常难过。。我在服务器
var_dump $_SERVER 和 $_REQUEST 请求方法永远是GET 永远没有数据,后来我突然发现是重定向的问题,一旦重定向之后服务器就会给你导向一个新的URL,并且已GET的方式,不携带任何数据.
更加详细的见下面代码
<?php
function runRequest($verb, $uri, $data)
$params = array(
'http' => array(
'method' => $verb,
'ignore_errors' => true,
'header' => "Accept: application/json\r\n"
. "Cache-Control: no-cache\r\n"
. "Pragma: no-cache\r\n"
)
); if ($verb == 'POST') {
if (is_array($data)) {
$str = http_build_query($data);
} else {
$str = $data;
} $params['http']['header'] .= "Content-type: application/x-www-form-urlencoded\r\n"
. 'Content-Length: '.strlen($str)."\r\n";
$params['http']['content'] = $str;
} $ctx = stream_context_create($params); $fp = @fopen($uri, 'rb', false, $ctx);
if (!$fp) {
print "runReq.fail:$verb-$uri";
// throw new Exception('Problem with '.$verb.' '.$uri);
} $output = @stream_get_contents($fp);
$headers = @stream_get_meta_data($fp); fclose($fp); unset($fp);
unset($ctx);
unset($str);
unset($params);
// unset($verb); var_dump($headers); var_dump($output);
}
?> a.php (does the redirect)
============ <?php
header('Location: /b.php', true, 302);
?> b.php
=================
<?php
var_dump($_REQUEST);
var_dump($_SERVER);
?> When I run client.php, this is the response: ...truncated ... ["SERVER_ADMIN"]=>
string(15) "you@example.com"
["SCRIPT_FILENAME"]=>
string(26) "/Users/moz/Sites/exp/b.php"
["REMOTE_PORT"]=>
string(5) "56070"
["GATEWAY_INTERFACE"]=>
string(7) "CGI/1.1"
["SERVER_PROTOCOL"]=>
string(8) "HTTP/1.0"
["REQUEST_METHOD"]=>
string(3) "GET"
["QUERY_STRING"]=>
string(0) ""
["REQUEST_URI"]=>
string(6) "/b.php"
["SCRIPT_NAME"]=>
string(6) "/b.php"
["PHP_SELF"]=>
string(6) "/b.php"
["REQUEST_TIME"]=>
int(1334249770)
}
array(0) {
}
array(5) {
["Host"]=>
string(8) "expo.dev"
["Accept"]=>
string(16) "application/json"
["Cache-Control"]=>
string(8) "no-cache"
["Pragma"]=>
string(8) "no-cache"
["Content-type"]=>
string(33) "application/x-www-form-urlencoded"
}
"
PHP - 模拟HTTP请求, stream_context_create 和 fopen 和 fsockopen的更多相关文章
- php模拟POST请求提交数据
php模拟POST请求提交数据 1.基于fsockopen function phppost00($jsonString){ $URL='https://www.jy.com/phppostok.ph ...
- php curl模拟post请求提交数据样例总结
在php中要模拟post请求数据提交我们会使用到curl函数,以下我来给大家举几个curl模拟post请求提交数据样例有须要的朋友可參考參考.注意:curl函数在php中默认是不被支持的,假设须要使用 ...
- php curl模拟post请求的例子
curl 在php中要模拟post请求数据提交我们会使用到curl函数,下面我来给大家举几个curl模拟post请求提交数据例子有需要的朋友可参考参考. 注意:curl函数在php中默认是不被支持的, ...
- php curl模拟post请求提交数据例子总结
php curl模拟post请求提交数据例子总结 [导读] 在php中要模拟post请求数据提交我们会使用到curl函数,下面我来给大家举几个curl模拟post请求提交数据例子有需要的朋友可参考参考 ...
- ASP模拟POST请求异步提交数据的方法
这篇文章主要介绍了ASP模拟POST请求异步提交数据的方法,本文使用MSXML2.SERVERXMLHTTP.3.0实现POST请求,需要的朋友可以参考下 有时需要获取远程网站的某些信息,而服务器又限 ...
- java模拟post请求发送json
java模拟post请求发送json,用两种方式实现,第一种是HttpURLConnection发送post请求,第二种是使用httpclient模拟post请求, 方法一: package main ...
- C# 通过模拟http请求来调用soap、wsdl
C#调用webservice的方法很多,我说的这种通过http请求模拟来调用的方式是为了解决C#调用java的远程API出现各种不兼容问题. 由于远程API不在我们的控制下,我们只能修改本地的调用代码 ...
- 关于模拟http请求 cookie的赋值
最近的工作一直是关于模拟http请求方面的知识的. 原本以为很简单,就是简单模拟一下http请求.先用fiddler模拟一下请求,验证接口可用,就直接上代码. 但是在模拟一个联通http的请求时候,我 ...
- HttpClient方式模拟http请求设置头
关于HttpClient方式模拟http请求,请求头以及其他参数的设置. 本文就暂时不给栗子了,当作简版参考手册吧. 发送请求是设置请求头:header HttpClient httpClient = ...
随机推荐
- POJ2891 Strange Way to Express Integers【扩展中国剩余定理】
题目大意 就是模板...没啥好说的 思路 因为模数不互质,所以直接中国剩余定理肯定是不对的 然后就考虑怎么合并两个同余方程 \(ans = a_1 + x_1 * m_1 = a_2 + x_2 * ...
- Hexo+GitHub+Netlify一站式搭建属于自己的博客网站
喜欢的话请关注我的个人博客我在马路边https://hhongwen.cn/,此文为博主原创,转载请标明出处. 更好的阅读体验请点击查看:Hexo+GitHub+Netlify一站式搭建属于自己的博客 ...
- Makefile常用知识点
格式 目标:最终要去生成的文件, 定格写,后面是冒号(冒号后面是依赖) 依赖:用来生成目标的源材料 命令:加工的方法,命令前面一定是Tab, make的过程就是使用命令将依赖加工成目标的过程 工作原理 ...
- HTTP 协议小结
本篇博客来自前辈整理资料的学习之作,若有冒犯,敬请谅解!原文博客已删除,转载篇:HTTP协议详解 1,HTTP特点 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于 ...
- #231-D: declaration is not visible outside of function
通常出现在.h中的函数声明,函数声明中的变量用到了.h当中没有的变量形式,比如特殊定义的结构体
- PHP RSA加签的实现过程
一.得到私钥文件mycert.key 2.从pfx提取密钥信息,并转换为key格式(pfx使用pkcs12模式补足) (1)提取密钥对 openssl pkcs12 -in 1.pfx -nocert ...
- Android 从上层到底层-----app层
CPU:RK3288 系统:Android 5.1 功能:上层 app 控制 led 亮灭 开发板:Firefly RK3288 MainActivity.java package com.aaron ...
- stm32f0系列在SWD模式下载时复位失败
用stm32f030K6T6做了个小玩意,仿真电路就直接把3.3V,SWDIO,SWCLK,GND引出来连接到j-link的这四个角上,SWDIO和SWCLK引脚既没有上拉也没有下拉. MCU ...
- 理解C/C++中const char*、char* const、const char* const、char* const*等等
先说些题外话,今天学习execve(2)的使用,由于书上代码使用的是C89标准,所以下面这种代码都被我修改了 char* s[] = { "aaa", "bbb" ...
- 基于INTEL FPGA硬浮点DSP实现卷积运算
概述 卷积是一种线性运算,其本质是滑动平均思想,广泛应用于图像滤波.而随着人工智能及深度学习的发展,卷积也在神经网络中发挥重要的作用,如卷积神经网络.本参考设计主要介绍如何基于INTEL 硬浮点的DS ...