一、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的更多相关文章

  1. php模拟POST请求提交数据

    php模拟POST请求提交数据 1.基于fsockopen function phppost00($jsonString){ $URL='https://www.jy.com/phppostok.ph ...

  2. php curl模拟post请求提交数据样例总结

    在php中要模拟post请求数据提交我们会使用到curl函数,以下我来给大家举几个curl模拟post请求提交数据样例有须要的朋友可參考參考.注意:curl函数在php中默认是不被支持的,假设须要使用 ...

  3. php curl模拟post请求的例子

    curl 在php中要模拟post请求数据提交我们会使用到curl函数,下面我来给大家举几个curl模拟post请求提交数据例子有需要的朋友可参考参考. 注意:curl函数在php中默认是不被支持的, ...

  4. php curl模拟post请求提交数据例子总结

    php curl模拟post请求提交数据例子总结 [导读] 在php中要模拟post请求数据提交我们会使用到curl函数,下面我来给大家举几个curl模拟post请求提交数据例子有需要的朋友可参考参考 ...

  5. ASP模拟POST请求异步提交数据的方法

    这篇文章主要介绍了ASP模拟POST请求异步提交数据的方法,本文使用MSXML2.SERVERXMLHTTP.3.0实现POST请求,需要的朋友可以参考下 有时需要获取远程网站的某些信息,而服务器又限 ...

  6. java模拟post请求发送json

    java模拟post请求发送json,用两种方式实现,第一种是HttpURLConnection发送post请求,第二种是使用httpclient模拟post请求, 方法一: package main ...

  7. C# 通过模拟http请求来调用soap、wsdl

    C#调用webservice的方法很多,我说的这种通过http请求模拟来调用的方式是为了解决C#调用java的远程API出现各种不兼容问题. 由于远程API不在我们的控制下,我们只能修改本地的调用代码 ...

  8. 关于模拟http请求 cookie的赋值

    最近的工作一直是关于模拟http请求方面的知识的. 原本以为很简单,就是简单模拟一下http请求.先用fiddler模拟一下请求,验证接口可用,就直接上代码. 但是在模拟一个联通http的请求时候,我 ...

  9. HttpClient方式模拟http请求设置头

    关于HttpClient方式模拟http请求,请求头以及其他参数的设置. 本文就暂时不给栗子了,当作简版参考手册吧. 发送请求是设置请求头:header HttpClient httpClient = ...

随机推荐

  1. Page View Controllers

    Page View Controllers You use a page view controller to present content in a page-by-page manner. A ...

  2. JavaScript年月日和时间戳互转

    /** 一丶将日期单位转为时间戳 / 毫秒 **/ var str="2017年06月2日" var time = str.replace(/年/i,"-"). ...

  3. 用Python做图像处理

    转自:http://blog.csdn.net/gzlaiyonghao/article/details/1852726  最近在做一件比较 evil 的事情——验证码识别,以此来学习一些新的技能.因 ...

  4. spring事务中隔离级别和spring的事务传播机制

    Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废. 事务也是这样,不能做一般就不做了,要么做完,要 么就不做.也就是说,事务必须是 ...

  5. 【最全 干货 实例】 缓存手册(Memcached、redis、RabbitMQ)

    http://www.cnblogs.com/suoning/p/5807247.html 本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 re ...

  6. ballerina 学习十 streams

    ballerina 的streams 使用的是siddhi complex event processing 引擎处理,可以包含的语法有 projection filtering windows jo ...

  7. Spring Cloud feign 服务超时处理

    Spring Cloud中,Feign和Ribbon在整合了Hystrix后,可能会出现首次调用失败的问题 造成该问题的原因 Hystrix默认的超时时间是1秒,如果超过这个时间尚未响应,将会进入fa ...

  8. callback&&callback()

    如果存在回调函数就执行!这是利用了 JS &&符号的一个小技巧&& 符号在前面为假时就不会执行后面的语句了所以这个就相当于 if(callback){ callback ...

  9. proxool 连接池

    今天配置proxool 连接池,发现可配置属性非常多,以前也只是用,没总结过,今天查了下网上的资料,总结一下 方便你我.其实网上很多英文资料都很全,网上很多人就是考翻译老外的文章赚些流量,其实也没啥意 ...

  10. mysql命令之二:查看mysql版本的四种方法

    1:在终端下:mysql -V. 以下是代码片段: [shengting@login ~]$ mysql -V mysql Ver 14.7 Distrib 4.1.10a, for redhat-l ...