在开发中,我们碰到的跨域主要还是纠结在IE,页面中的IFRAME或者FRAME或者JS跨域的时候,IE有安全策略限制页面不带cookie,但是如果我们加上P3P,就没有这策略的限制。这也是P3P来突破跨域的可行前提,在访问b.com域后,设置了a.com域的cookie值。
在开发中,我们碰到的跨域主要还是纠结在IE,页面中的IFRAME或者FRAME或者JS跨域的时候,IE有安全策略限制页面不带cookie,但是如果我们加上P3P,就没有这策略的限制。这也是P3P来突破跨域的可行前提。
此次来两个不同域名,用IE6测试一下试一下,实践来源:http://blog.163.com/niuzai369@126/blog/static/3743091520122733733736/
它里面的www.a.com就是咱们对应的www.naimanqi.com.cn,而www.b.com则对应www.naimanqi.cn,如下:
cat /data/htdocs/naimanqi.com.cn/a_setcookie.php
<?php setcookie("test", $_GET['id'], time()+3600, "/", ".naimanqi.com.cn"); ?>
cat /data/htdocs/naimanqi.com.cn/a_getcookie.php
<?php var_dump($_COOKIE); ?>
cat /data/htdocs/naimanqi.cn/b_setcookie.php
<script src="http://www.naimanqi.com.cn/a_setcookie.php?id=www.naimanqi.com.cn"></script>
在IE9和FF和Chrome如下:
http://www.naimanqi.cn/b_setcookie.php
http://www.naimanqi.com.cn/a_getcookie.php
array(1) { ["test"]=> string(19) "www.naimanqi.com.cn" }
但是在IE6下就没法输出这个:
array(1) { ["test"]=> string(19) "www.naimanqi.com.cn" }
将http://www.naimanqi.com.cn/a_setcookie.php文件内容改为如下:
<?php
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
setcookie("test", $_GET['id'], time()+3600, "/", ".naimanqi.com.cn");
?>
在ie6下访问http://www.naimanqi.cn/b_setcookie.php域后,设置了www.naimanqi.com.cn域的cookie值。
http://www.naimanqi.cn/b_setcookie.php
http://www.naimanqi.com.cn/a_getcookie.php
array(1) { ["test"]=> string(19) "www.naimanqi.com.cn" }
===========================同域名不同二级域名的实践如下=============================
从上面例子可以看出通过发送P3P头信息而实现的跨域。(在Firefox不发送P3P也能跨域成功)IE高版本也是可以的-AddTime:2016-08-16。
实践一下:
1)b.jackxiang.com/test.html
2)a.jackxiang.com/test.php
此时我们请求 http://b.jackxiang.com/test.html , 他包含一个iframe,会去跨域请求 http://a.jackxiang.com/test.php ,该php页面会尝试 set-cookie。
第一次请求, test.php 会 set-cookie,所以浏览器会收到一个cookie。
理论上认为:
如果 set-cookie 成功,再次请求该页面,浏览器应该会 sent 刚才 recieve 到的cookie。
问题出现了:
可是由于前面说的跨域限制,在IE里的iframe标签是 set-cookie不成功的,所以无法sent刚才收到的cookie。 这里无论是 session cookie 还是本地cookie都是一样。(这里说的是第一次是能收到php设置的cookie的,是再次发起请求时,这个cookie没有在http头里,我用IE10好像不存在这个问题。:(难道 是我安全级别设置太低了?NO,是二级域名相同的问题,哈哈)
实际上看到:
可以看到:
第一次访问:b.jackxiang.com/test.html 出现:alert空。
第二次发包,还是没能sent出去cookie,用Httpwatcher抓包发现cookie是空的。
______________________________________
原因是:以 Internet Explorer 为例,默认情况下,IE的隐私策略如下图所设:
请注意其中这一条:阻止保存可用来联系您的信息而没有您的明确同意的第三方Cookie。 //做互联网那帮起草的人为用户安全着想把权限给用户了,我们程序员被困住了,因为需求:如多个站群的登录的简单实现,辨别等所谓跨站跟踪,行为分析啥的又很有必要。
但是这种情况在加入了P3P header 后会改变。
P3P header允许跨域访问隐私数据,从而可以跨域set-cookie成功
我们修改 http://a.jackxiang.com/test.php 为:
再次访问两次上面的测试过程:
可以看到第二个包已经发送出了收到的cookie
而我们写的javascript也能够弹出cookie了。
我修改成:test=jack,再修改再访问,没有被修改,还是jack,果然不会被修改。
值得注意的是,P3P header只需要设置一次,这样跟在这个P3P header后面的所有 set-cookie,都可以跨域访问了。也就是说: 被P3P header设置过一次后,之后的请求不再需要P3P header,也能够在iframe里跨域发送这些cookie。
但是如果用 set-cookie 去改变设置好的cookie,则不再具有这种跨域访问特性。
P3P header 还有一个特点就是同一个包里只能设置一次,后面的P3P Header不会覆盖前面的P3P header,浏览器只认第一个。
用fiddler抓包看下,这个cookie是怎么设置的呢?
去的请求有没有带cookie,显示:
This request did not send any cookie data.
回来的cookie显示(证明是在服务器回来时就设计了,js再读取出来的,达到了一次就读取,其这个给学习带来难度,往往出现感觉这个cookie是在客户端设置的假象,其实是php的header设置后,前端用js去立即读取,这样一个流程情况):
Response sent 80 bytes of Cookie data:
Set-Cookie: test=jack; expires=Sun, 23-Dec-2018 08:13:02 GMT; domain=.a.jackxiang.com; path=/
P3P Header is present:
CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR
!ERROR! P3P Compact Policy string is not properly quoted.
Validate P3P Policies at: http://www.w3.org/P3P/validator.html
Learn more at: http://fiddler2.com/r/?p3pinfo
其本质就是相当于通过b.jackxiang.com这个域名的php脚本给a.jackxiang.com这个域下设置了一个cookie变量,且是合法的一种办法,用Httpwatcher就会看到如下:
test Sent jack / .a.jackxiang.com (Session) No No
test2 Sent jack2 / .a.jackxiang.com (Session) No No
实践来源:http://www.cnblogs.com/ccdc/archive/2012/05/08/2489535.html
————————————————————————————————————————————————————————————————————————
============================之前的参考如下:======================================
P3P 是说,在页面中 iframe 或者 frame 或者 js 时候,IE 会有安全策略限制 这些页面不带cookie 。如果加上P3P 则没有这个限制。
来自:http://hi.baidu.com/houdelei250/blog/item/da1ad135f0c39147251f14bd.html
http://blog.163.com/niuzai369@126/blog/static/3743091520122733733736/
实际工作中,类似这样的要求很多,比如说,我们有两个域名,我们想实现在一个域名登录后,能自动完成另一个域名的登录,也就是PASSPORT的功能。
我只写一个大概,为了测试的方便,先编辑hosts文件,加入测试域名(C:\WINDOWS\system32\drivers\etc\hosts)
127.0.0.1 www.a.com
127.0.0.1 www.b.com
首先:创建 a_setcookie.php 文件,内容如下:
然后:创建 a_getcookie.php 文件,内容如下:
最后:创建 b_setcookie.php 文件,内容如下:
<script src="http://www.a.com/a_setcookie.php?id=www.b.com"></script>
----------------------------
三个文件创建完毕后,我们通过浏览器依次访问:
http://www.b.com/b_setcookie.php
http://www.a.com/a_getcookie.php
我们会发现,在访问b.com域的时候,我们并没有在a.com域设置上cookie值。
然后我们修改一下a_setcookie.php文件,去掉注释符号,a_setcookie.php即为:
再次通过浏览器依次访问:
http://www.b.com/b_setcookie.php
http://www.a.com/a_getcookie.php
这次,你会发现在访问b.com域的时候,我们设置了a.com域的cookie值。
末了补充一句,似乎只有IE对跨域访问COOKIE限制比较严格,上述代码在FIREFOX下测试,即使不发送P3P头信息,也能成功。
==========================================
阅读全文
在开发中,我们碰到的跨域主要还是纠结在IE,页面中的IFRAME或者FRAME或者JS跨域的时候,IE有安全策略限制页面不带cookie,但是如果我们加上P3P,就没有这策略的限制。这也是P3P来突破跨域的可行前提。
此次来两个不同域名,用IE6测试一下试一下,实践来源:http://blog.163.com/niuzai369@126/blog/static/3743091520122733733736/
它里面的www.a.com就是咱们对应的www.naimanqi.com.cn,而www.b.com则对应www.naimanqi.cn,如下:
cat /data/htdocs/naimanqi.com.cn/a_setcookie.php
<?php setcookie("test", $_GET['id'], time()+3600, "/", ".naimanqi.com.cn"); ?>
cat /data/htdocs/naimanqi.com.cn/a_getcookie.php
<?php var_dump($_COOKIE); ?>
cat /data/htdocs/naimanqi.cn/b_setcookie.php
<script src="http://www.naimanqi.com.cn/a_setcookie.php?id=www.naimanqi.com.cn"></script>
在IE9和FF和Chrome如下:
http://www.naimanqi.cn/b_setcookie.php
http://www.naimanqi.com.cn/a_getcookie.php
array(1) { ["test"]=> string(19) "www.naimanqi.com.cn" }
但是在IE6下就没法输出这个:
array(1) { ["test"]=> string(19) "www.naimanqi.com.cn" }
将http://www.naimanqi.com.cn/a_setcookie.php文件内容改为如下:
<?php
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
setcookie("test", $_GET['id'], time()+3600, "/", ".naimanqi.com.cn");
?>
在ie6下访问http://www.naimanqi.cn/b_setcookie.php域后,设置了www.naimanqi.com.cn域的cookie值。
http://www.naimanqi.cn/b_setcookie.php
http://www.naimanqi.com.cn/a_getcookie.php
array(1) { ["test"]=> string(19) "www.naimanqi.com.cn" }
===========================同域名不同二级域名的实践如下=============================
从上面例子可以看出通过发送P3P头信息而实现的跨域。(在Firefox不发送P3P也能跨域成功)IE高版本也是可以的-AddTime:2016-08-16。
实践一下:
1)b.jackxiang.com/test.html
2)a.jackxiang.com/test.php
此时我们请求 http://b.jackxiang.com/test.html , 他包含一个iframe,会去跨域请求 http://a.jackxiang.com/test.php ,该php页面会尝试 set-cookie。
第一次请求, test.php 会 set-cookie,所以浏览器会收到一个cookie。
理论上认为:
如果 set-cookie 成功,再次请求该页面,浏览器应该会 sent 刚才 recieve 到的cookie。
问题出现了:
可是由于前面说的跨域限制,在IE里的iframe标签是 set-cookie不成功的,所以无法sent刚才收到的cookie。 这里无论是 session cookie 还是本地cookie都是一样。(这里说的是第一次是能收到php设置的cookie的,是再次发起请求时,这个cookie没有在http头里,我用IE10好像不存在这个问题。:(难道 是我安全级别设置太低了?NO,是二级域名相同的问题,哈哈)
实际上看到:
可以看到:
第一次访问:b.jackxiang.com/test.html 出现:alert空。
第二次发包,还是没能sent出去cookie,用Httpwatcher抓包发现cookie是空的。
______________________________________
原因是:以 Internet Explorer 为例,默认情况下,IE的隐私策略如下图所设:
请注意其中这一条:阻止保存可用来联系您的信息而没有您的明确同意的第三方Cookie。 //做互联网那帮起草的人为用户安全着想把权限给用户了,我们程序员被困住了,因为需求:如多个站群的登录的简单实现,辨别等所谓跨站跟踪,行为分析啥的又很有必要。
但是这种情况在加入了P3P header 后会改变。
P3P header允许跨域访问隐私数据,从而可以跨域set-cookie成功
我们修改 http://a.jackxiang.com/test.php 为:
再次访问两次上面的测试过程:
可以看到第二个包已经发送出了收到的cookie
而我们写的javascript也能够弹出cookie了。
我修改成:test=jack,再修改再访问,没有被修改,还是jack,果然不会被修改。
值得注意的是,P3P header只需要设置一次,这样跟在这个P3P header后面的所有 set-cookie,都可以跨域访问了。也就是说: 被P3P header设置过一次后,之后的请求不再需要P3P header,也能够在iframe里跨域发送这些cookie。
但是如果用 set-cookie 去改变设置好的cookie,则不再具有这种跨域访问特性。
P3P header 还有一个特点就是同一个包里只能设置一次,后面的P3P Header不会覆盖前面的P3P header,浏览器只认第一个。
用fiddler抓包看下,这个cookie是怎么设置的呢?
去的请求有没有带cookie,显示:
This request did not send any cookie data.
回来的cookie显示(证明是在服务器回来时就设计了,js再读取出来的,达到了一次就读取,其这个给学习带来难度,往往出现感觉这个cookie是在客户端设置的假象,其实是php的header设置后,前端用js去立即读取,这样一个流程情况):
Response sent 80 bytes of Cookie data:
Set-Cookie: test=jack; expires=Sun, 23-Dec-2018 08:13:02 GMT; domain=.a.jackxiang.com; path=/
P3P Header is present:
CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR
!ERROR! P3P Compact Policy string is not properly quoted.
Validate P3P Policies at: http://www.w3.org/P3P/validator.html
Learn more at: http://fiddler2.com/r/?p3pinfo
其本质就是相当于通过b.jackxiang.com这个域名的php脚本给a.jackxiang.com这个域下设置了一个cookie变量,且是合法的一种办法,用Httpwatcher就会看到如下:
test Sent jack / .a.jackxiang.com (Session) No No
test2 Sent jack2 / .a.jackxiang.com (Session) No No
实践来源:http://www.cnblogs.com/ccdc/archive/2012/05/08/2489535.html
————————————————————————————————————————————————————————————————————————
============================之前的参考如下:======================================
P3P 是说,在页面中 iframe 或者 frame 或者 js 时候,IE 会有安全策略限制 这些页面不带cookie 。如果加上P3P 则没有这个限制。
来自:http://hi.baidu.com/houdelei250/blog/item/da1ad135f0c39147251f14bd.html
http://blog.163.com/niuzai369@126/blog/static/3743091520122733733736/
实际工作中,类似这样的要求很多,比如说,我们有两个域名,我们想实现在一个域名登录后,能自动完成另一个域名的登录,也就是PASSPORT的功能。
我只写一个大概,为了测试的方便,先编辑hosts文件,加入测试域名(C:\WINDOWS\system32\drivers\etc\hosts)
127.0.0.1 www.a.com
127.0.0.1 www.b.com
首先:创建 a_setcookie.php 文件,内容如下:
然后:创建 a_getcookie.php 文件,内容如下:
最后:创建 b_setcookie.php 文件,内容如下:
<script src="http://www.a.com/a_setcookie.php?id=www.b.com"></script>
----------------------------
三个文件创建完毕后,我们通过浏览器依次访问:
http://www.b.com/b_setcookie.php
http://www.a.com/a_getcookie.php
我们会发现,在访问b.com域的时候,我们并没有在a.com域设置上cookie值。
然后我们修改一下a_setcookie.php文件,去掉注释符号,a_setcookie.php即为:
再次通过浏览器依次访问:
http://www.b.com/b_setcookie.php
http://www.a.com/a_getcookie.php
这次,你会发现在访问b.com域的时候,我们设置了a.com域的cookie值。
末了补充一句,似乎只有IE对跨域访问COOKIE限制比较严格,上述代码在FIREFOX下测试,即使不发送P3P头信息,也能成功。
==========================================

网页的Refer来源判断代码:
[codes=html]
$refer = strtolower($_SERVER['HTTP_REFERER']);
$check = preg_match('/[.]qq[.]com/',$refer);
if(empty($check))
{
echo '{"code":"-200",msg":"温馨提示:请求来源非法"}';
exit;
}
[codes]
[codes=html]
$refer = strtolower($_SERVER['HTTP_REFERER']);
$check = preg_match('/[.]qq[.]com/',$refer);
if(empty($check))
{
echo '{"code":"-200",msg":"温馨提示:请求来源非法"}';
exit;
}
[codes]
[个人原创]PHP除开Post,Get外的提交方式外还有PHP输入流php://input
Php/Js/Shell/Go jackxiang 2011-7-21 14:39
突然问道让你回答:PHP除开Post,Get外还有什么提交方式?
相册-耀京-腾讯(50314234) 16:35:28
cookie
博客-武建(569676660) 16:35:59
socket
RD-解超-赶集(75744317) 16:36:11
socket应该是正解吧。。。
博客-路人甲(285882507) 16:36:14
SESSION
-----
蒙了,下来才想起,经常调试Flash图片的上传流不就是一个非Get,非Post的方式嘛。
HTTP_RAW_POST_DATA PHP输入流
越来越发现缺少思考,或者说总结归纳不够罢。
====================================================================
来处网上 http://www.5iphp.com/zh-hans/content/483.html:
通过Flash POST 图片的二进制数据给php,由php生成图片保存。
开始想到用$_POST来接受。后来发现行不通。
查阅了很多资料 明白了所以然,这里做一个笔记:
于PHP默认只识别application/x-www.form-urlencoded标准的数据类型。
因此,对型如text/xml 或者 soap 或者 application/octet-stream 之类的内容无法解析,如果用$_POST数组来接收就会失败!
故保留原型,交给$GLOBALS['HTTP_RAW_POST_DATA'] 来接收。
另外还有一项 php://input 也可以实现此这个功能
php://input 允许读取 POST 的原始数据。和 $HTTP_RAW_POST_DATA 比起来,它给内存带来的压力较小,并且不需要任何特殊的 php.ini 设置。php://input和 $HTTP_RAW_POST_DATA 不能用于 enctype="multipart/form-data"。
我在Flash中使用JPGEncoder把BitMapData转成二进制,然后post给php
php页面代码如下:
http://www.jackxiang.com/post/4411/
务必参考:http://www.perfgeeks.com/?p=150
时间上面的文章如下,可能根据实际情况做下代码变通:
在使用xml-rpc的时候,server端获取client数据,主要是通过php输入流input,而不是$_POST数组。所以,这里主要探讨php输入流php://input
对一php://input介绍,PHP官方手册文档有一段话对它进行了很明确地概述。
“php://input allows you to read raw POST data. It is a less memory intensive alternative to $HTTP_RAW_POST_DATA and does not need any special php.ini directives. php://input is not available with enctype=”multipart/form-data”.
翻译过来,是这样:
“php://input可以读取没有处理过的POST数据。相较于$HTTP_RAW_POST_DATA而言,它给内存带来的压力较小,并且不需要特殊的php.ini设置。php://input不能用于enctype=multipart/form-data”
我们应该怎么去理解这段概述呢?!我把它划分为三部分,逐步去理解。
读取POST数据
不能用于multipart/form-data类型
php://input VS $HTTP_RAW_POST_DATA
读取POST数据
PHPer们一定很熟悉$_POST这个内置变量。$_POST与php://input存在哪些关联与区别呢?另外,客户端向服务端交互数据,最常用的方法除了POST之外,还有GET。既然php://input作为PHP输入流,它能读取GET数据吗?这二个问题正是我们这节需要探讨的主要内容。
经验告诉我们,从测试与观察中总结,会是一个很凑效的方法。这里,我写了几个脚本来帮助我们测试。
@file 172.25.38.70:/phpinput_server.php 打印出接收到的数据
@file 172.25.38.70:/phpinput_post.php 模拟以POST方法提交表单数据
@file 172.25.38.70:/phpinput_xmlrpc.php 模拟以POST方法发出xmlrpc请求.
@file 172.25.38.70:/phpinput_get.php 模拟以GET方法提交表单表数
phpinput_server.php与phpinput_post.php
我们可以通过使用工具ngrep抓取http请求包(因为我们需要探知的是php://input,所以我们这里只抓取http Request数据包)。我们来执行测试脚本phpinput_post.php
结果:
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 04:00:58 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 175
Connection: close
Content-Type: text/html; charset=utf-8
-------$_POST------------------
array(2) {
["name"]=>
string(9) "jackxiang"
["idnum"]=>
string(4) "7788"
}
-------php://input-------------
name=jackxiang&idnum=7788
仔细观察,我们不难发现
1,$_POST数据,php://input 数据与httpd entity body数据是“一致”的
2,http请求中的Content-Type是application/x-www-form-urlencoded ,它表示http请求body中的数据是使用http的post方法提交的表单数据,并且进行了urlencode()处理。
我们再来看看脚本phpinput_xmlrpc.php的原文件内容,它模拟了一个POST方法提交的xml-rpc请求。
结果如下:
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 03:56:41 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 151
Connection: close
Content-Type: text/html; charset=utf-8
-------$_GET------------------
array(0) {
}
-------php://input-------------
<?xml version="1.0"> <methodcall> <name>jt_userinfo</name> </methodcall>
同样,我样也可以很容易地发现:
1,http请求中的Content-Type是text/xml。它表示http请求中的body数据是xml数据格式。
2,服务端$_POST打印出来的是一个空数组,即与http entity body不一致了。这跟上个例子不一样了,这里的Content-Type是text/xml,而不是application/x-www-form-urlencoded
3,而php://input数据还是跟http entity body数据一致。也就是php://input数据和$_POST数据不一致了。
我们再来看看通过GET方法提交表单数据的情况,php://input能不能读取到GET方法的表单数据?在这里,我们稍加改动一下phpinput_server.php文件,将$_POST改成$_GET。
同样,我们执行下一phpinput_get.php测试脚本,它模拟了一个通常情况下的GET方法提交表单数据。
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 03:59:38 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 149
Connection: close
Content-Type: text/html; charset=utf-8
-------$_GET------------------
array(2) {
["name"]=>
string(9) "jackxiang"
["idnum"]=>
string(4) "7788"
}
-------php://input-------------
比较POST方法提交的http请求,通常GET方法提交的请求中,entity body为空。同时,不会指定Content-Type和Content-Length。但是,如果强硬数据http entity body,并指明正确地Content-Type和Content-Length,那么php://input还可是读取得到http entity body数据,但不是$_GET数据。
所根据,上面几个探测,我们可以作出以下总结:
1,Content-Type取值为application/x-www-form-urlencoded时,php会将http请求body相应数据会填入到数组$_POST,填入到$_POST数组中的数据是进行urldecode()解析的结果。(其实,除了该Content-Type,还有multipart/form-data表示数据是表单数据,稍后我们介绍)
2,php://input数据,只要Content-Type不为multipart/form-data(该条件限制稍后会介绍)。那么php://input数据与http entity body部分数据是一致的。该部分相一致的数据的长度由Content-Length指定。
3,仅当Content-Type为application/x-www-form-urlencoded且提交方法是POST方法时,$_POST数据与php://input数据才是”一致”(打上引号,表示它们格式不一致,内容一致)的。其它情况,它们都不一致。
4,php://input读取不到$_GET数据。是因为$_GET数据作为query_path写在http请求头部(header)的PATH字段,而不是写在http请求的body部分。
这也帮助我们理解了,为什么xml_rpc服务端读取数据都是通过file_get_contents(‘php://input’, ‘r’)。而不是从$_POST中读取,正是因为xml_rpc数据规格是xml,它的Content-Type是text/xml。
php://input碰到了multipart/form-data
上传文件的时候,表单的写法是这样的
那么,enctype=multipart/form-data这里的意义,就是将该次http请求头部(head)中的Content-Type设置为multipart/form-data。请查阅RFC1867对它的描述。multipart/form-data也表示以POST方法提交表单数据,它还伴随了文件上传,所以会跟application/x-www-form-urlencoded数据格式不一样。它会以一更种更合理的,更高效的数据格式传递给服务端。我们提交该表单数据,并且打印出响应结果,如下:
-------$_POST------------------
array(1) {
["n"]=>
string(9) "jackxiang"
}
-------php://input-------------
同时,我们通过ngrep抓取的相应的http请求数据包如下:
multipart/form-data; boundary=---------------------------7db9cf5042a
-----------------------------7db9cf5042a
Content-Disposition: form-data; name="n"
jackxiang
-----------------------------7db9cf5042a
Content-Disposition: form-data; name="f"; filename="yxp.jpg"
Content-Type: image/bmp
BM�
从响应输出来比对,$_POST数据跟请求提交数据相符,即$_POST = array(‘n’ => ‘perfgeeks’)。这也跟http请求body中的数据相呼应,同时说明PHP把相应的数据填入$_POST全局变量。而php://input输出为空,没有输出任何东西,尽管http请求数据包中body不为空。这表示,当Content-Type为multipart/form-data的时候,即便http请求body中存在数据,php://input也为空,PHP此时,不会把数据填入php://input流。所以,可以确定: php://input不能用于读取enctype=multipart/form-data数据。
我们再比较这次通过ngrep抓取的http请求数据包,我们会发现,最大不同的一点是Content-Type后面跟了boundary定义了数据的分界符,bounday是随机生成的。另外一个大不一样的,就是http entity body中的数据组织结构不一样了。
上一节,我们概述了,当Content-Type为application/x-www-form-urlencoded时,php://input和$_POST数据是“一致”的,为其它Content-Type的时候,php://input和$_POST数据数据是不一致的。因为只有在Content-Type为application/x-www-form-urlencoded或者为multipart/form-data的时候,PHP才会将http请求数据包中的body相应部分数据填入$_POST全局变量中,其它情况PHP都忽略。而php://input除了在数据类型为multipart/form-data之外为空外,其它情况都可能不为空。通过这一节,我们更加明白了php://input与$_POST的区别与联系。所以,再次确认,php://input无法读取enctype=multipart/form-data数据,当php://input遇到它时,永远为空,即便http entity body有数据。
php://input VS $http_raw_post_data
相信大家对php://input已经有一定深度地了解了。那么$http_raw_post_data是什么呢?$http_raw_post_data是PHP内置的一个全局变量。它用于,PHP在无法识别的Content-Type的情况下,将POST过来的数据原样地填入变量$http_raw_post_data。它同样无法读取Content-Type为multipart/form-data的POST数据。需要设置php.ini中的always_populate_raw_post_data值为On,PHP才会总把POST数据填入变量$http_raw_post_data。
把脚本phpinput_server.php改变一下,可以验证上述内容
@php phpinput_post.php
@php phpinput_get.php
@php phpinput_xmlrpc.php
如下:
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 04:07:52 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 6
Connection: close
Content-Type: text/html; charset=utf-8
0
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 04:07:59 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 6
Connection: close
Content-Type: text/html; charset=utf-8
1
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 04:08:26 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 6
Connection: close
Content-Type: text/html; charset=utf-8
1
得出的结果输出都是一样的,即都为1,表示php://input和$HTTP_RAW_POST_DATA是相同的。至于对内存的压力,我们这里就不做细致地测试了。有兴趣的,可以通过xhprof进行测试和观察。
以此,我们这节可以总结如下:
1, php://input 可以读取http entity body中指定长度的值,由Content-Length指定长度,不管是POST方式或者GET方法提交过来的数据。但是,一般GET方法提交数据时,http request entity body部分都为空。
2,php://input 与$HTTP_RAW_POST_DATA读取的数据是一样的,都只读取Content-Type不为multipart/form-data的数据。
学习笔记
1,Coentent-Type仅在取值为application/x-www-data-urlencoded和multipart/form-data两种情况下,PHP才会将http请求数据包中相应的数据填入全局变量$_POST
2,PHP不能识别的Content-Type类型的时候,会将http请求包中相应的数据填入变量$HTTP_RAW_POST_DATA
3, 只有Coentent-Type不为multipart/form-data的时候,PHP不会将http请求数据包中的相应数据填入php://input,否则其它情况都会。填入的长度,由Coentent-Length指定。
4,只有Content-Type为application/x-www-data-urlencoded时,php://input数据才跟$_POST数据相一致。
5,php://input数据总是跟$HTTP_RAW_POST_DATA相同,但是php://input比$HTTP_RAW_POST_DATA更凑效,且不需要特殊设置php.ini
6,PHP会将PATH字段的query_path部分,填入全局变量$_GET。通常情况下,GET方法提交的http请求,body为空。
相册-耀京-腾讯(50314234) 16:35:28
cookie
博客-武建(569676660) 16:35:59
socket
RD-解超-赶集(75744317) 16:36:11
socket应该是正解吧。。。
博客-路人甲(285882507) 16:36:14
SESSION
-----
蒙了,下来才想起,经常调试Flash图片的上传流不就是一个非Get,非Post的方式嘛。
HTTP_RAW_POST_DATA PHP输入流
越来越发现缺少思考,或者说总结归纳不够罢。
====================================================================
来处网上 http://www.5iphp.com/zh-hans/content/483.html:
通过Flash POST 图片的二进制数据给php,由php生成图片保存。
开始想到用$_POST来接受。后来发现行不通。
查阅了很多资料 明白了所以然,这里做一个笔记:
于PHP默认只识别application/x-www.form-urlencoded标准的数据类型。
因此,对型如text/xml 或者 soap 或者 application/octet-stream 之类的内容无法解析,如果用$_POST数组来接收就会失败!
故保留原型,交给$GLOBALS['HTTP_RAW_POST_DATA'] 来接收。
另外还有一项 php://input 也可以实现此这个功能
php://input 允许读取 POST 的原始数据。和 $HTTP_RAW_POST_DATA 比起来,它给内存带来的压力较小,并且不需要任何特殊的 php.ini 设置。php://input和 $HTTP_RAW_POST_DATA 不能用于 enctype="multipart/form-data"。
我在Flash中使用JPGEncoder把BitMapData转成二进制,然后post给php
php页面代码如下:
http://www.jackxiang.com/post/4411/
务必参考:http://www.perfgeeks.com/?p=150
时间上面的文章如下,可能根据实际情况做下代码变通:
在使用xml-rpc的时候,server端获取client数据,主要是通过php输入流input,而不是$_POST数组。所以,这里主要探讨php输入流php://input
对一php://input介绍,PHP官方手册文档有一段话对它进行了很明确地概述。
“php://input allows you to read raw POST data. It is a less memory intensive alternative to $HTTP_RAW_POST_DATA and does not need any special php.ini directives. php://input is not available with enctype=”multipart/form-data”.
翻译过来,是这样:
“php://input可以读取没有处理过的POST数据。相较于$HTTP_RAW_POST_DATA而言,它给内存带来的压力较小,并且不需要特殊的php.ini设置。php://input不能用于enctype=multipart/form-data”
我们应该怎么去理解这段概述呢?!我把它划分为三部分,逐步去理解。
读取POST数据
不能用于multipart/form-data类型
php://input VS $HTTP_RAW_POST_DATA
读取POST数据
PHPer们一定很熟悉$_POST这个内置变量。$_POST与php://input存在哪些关联与区别呢?另外,客户端向服务端交互数据,最常用的方法除了POST之外,还有GET。既然php://input作为PHP输入流,它能读取GET数据吗?这二个问题正是我们这节需要探讨的主要内容。
经验告诉我们,从测试与观察中总结,会是一个很凑效的方法。这里,我写了几个脚本来帮助我们测试。
@file 172.25.38.70:/phpinput_server.php 打印出接收到的数据
@file 172.25.38.70:/phpinput_post.php 模拟以POST方法提交表单数据
@file 172.25.38.70:/phpinput_xmlrpc.php 模拟以POST方法发出xmlrpc请求.
@file 172.25.38.70:/phpinput_get.php 模拟以GET方法提交表单表数
phpinput_server.php与phpinput_post.php
我们可以通过使用工具ngrep抓取http请求包(因为我们需要探知的是php://input,所以我们这里只抓取http Request数据包)。我们来执行测试脚本phpinput_post.php
结果:
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 04:00:58 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 175
Connection: close
Content-Type: text/html; charset=utf-8
-------$_POST------------------
array(2) {
["name"]=>
string(9) "jackxiang"
["idnum"]=>
string(4) "7788"
}
-------php://input-------------
name=jackxiang&idnum=7788
仔细观察,我们不难发现
1,$_POST数据,php://input 数据与httpd entity body数据是“一致”的
2,http请求中的Content-Type是application/x-www-form-urlencoded ,它表示http请求body中的数据是使用http的post方法提交的表单数据,并且进行了urlencode()处理。
我们再来看看脚本phpinput_xmlrpc.php的原文件内容,它模拟了一个POST方法提交的xml-rpc请求。
结果如下:
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 03:56:41 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 151
Connection: close
Content-Type: text/html; charset=utf-8
-------$_GET------------------
array(0) {
}
-------php://input-------------
<?xml version="1.0"> <methodcall> <name>jt_userinfo</name> </methodcall>
同样,我样也可以很容易地发现:
1,http请求中的Content-Type是text/xml。它表示http请求中的body数据是xml数据格式。
2,服务端$_POST打印出来的是一个空数组,即与http entity body不一致了。这跟上个例子不一样了,这里的Content-Type是text/xml,而不是application/x-www-form-urlencoded
3,而php://input数据还是跟http entity body数据一致。也就是php://input数据和$_POST数据不一致了。
我们再来看看通过GET方法提交表单数据的情况,php://input能不能读取到GET方法的表单数据?在这里,我们稍加改动一下phpinput_server.php文件,将$_POST改成$_GET。
同样,我们执行下一phpinput_get.php测试脚本,它模拟了一个通常情况下的GET方法提交表单数据。
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 03:59:38 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 149
Connection: close
Content-Type: text/html; charset=utf-8
-------$_GET------------------
array(2) {
["name"]=>
string(9) "jackxiang"
["idnum"]=>
string(4) "7788"
}
-------php://input-------------
比较POST方法提交的http请求,通常GET方法提交的请求中,entity body为空。同时,不会指定Content-Type和Content-Length。但是,如果强硬数据http entity body,并指明正确地Content-Type和Content-Length,那么php://input还可是读取得到http entity body数据,但不是$_GET数据。
所根据,上面几个探测,我们可以作出以下总结:
1,Content-Type取值为application/x-www-form-urlencoded时,php会将http请求body相应数据会填入到数组$_POST,填入到$_POST数组中的数据是进行urldecode()解析的结果。(其实,除了该Content-Type,还有multipart/form-data表示数据是表单数据,稍后我们介绍)
2,php://input数据,只要Content-Type不为multipart/form-data(该条件限制稍后会介绍)。那么php://input数据与http entity body部分数据是一致的。该部分相一致的数据的长度由Content-Length指定。
3,仅当Content-Type为application/x-www-form-urlencoded且提交方法是POST方法时,$_POST数据与php://input数据才是”一致”(打上引号,表示它们格式不一致,内容一致)的。其它情况,它们都不一致。
4,php://input读取不到$_GET数据。是因为$_GET数据作为query_path写在http请求头部(header)的PATH字段,而不是写在http请求的body部分。
这也帮助我们理解了,为什么xml_rpc服务端读取数据都是通过file_get_contents(‘php://input’, ‘r’)。而不是从$_POST中读取,正是因为xml_rpc数据规格是xml,它的Content-Type是text/xml。
php://input碰到了multipart/form-data
上传文件的时候,表单的写法是这样的
那么,enctype=multipart/form-data这里的意义,就是将该次http请求头部(head)中的Content-Type设置为multipart/form-data。请查阅RFC1867对它的描述。multipart/form-data也表示以POST方法提交表单数据,它还伴随了文件上传,所以会跟application/x-www-form-urlencoded数据格式不一样。它会以一更种更合理的,更高效的数据格式传递给服务端。我们提交该表单数据,并且打印出响应结果,如下:
-------$_POST------------------
array(1) {
["n"]=>
string(9) "jackxiang"
}
-------php://input-------------
同时,我们通过ngrep抓取的相应的http请求数据包如下:
multipart/form-data; boundary=---------------------------7db9cf5042a
-----------------------------7db9cf5042a
Content-Disposition: form-data; name="n"
jackxiang
-----------------------------7db9cf5042a
Content-Disposition: form-data; name="f"; filename="yxp.jpg"
Content-Type: image/bmp
BM�
从响应输出来比对,$_POST数据跟请求提交数据相符,即$_POST = array(‘n’ => ‘perfgeeks’)。这也跟http请求body中的数据相呼应,同时说明PHP把相应的数据填入$_POST全局变量。而php://input输出为空,没有输出任何东西,尽管http请求数据包中body不为空。这表示,当Content-Type为multipart/form-data的时候,即便http请求body中存在数据,php://input也为空,PHP此时,不会把数据填入php://input流。所以,可以确定: php://input不能用于读取enctype=multipart/form-data数据。
我们再比较这次通过ngrep抓取的http请求数据包,我们会发现,最大不同的一点是Content-Type后面跟了boundary定义了数据的分界符,bounday是随机生成的。另外一个大不一样的,就是http entity body中的数据组织结构不一样了。
上一节,我们概述了,当Content-Type为application/x-www-form-urlencoded时,php://input和$_POST数据是“一致”的,为其它Content-Type的时候,php://input和$_POST数据数据是不一致的。因为只有在Content-Type为application/x-www-form-urlencoded或者为multipart/form-data的时候,PHP才会将http请求数据包中的body相应部分数据填入$_POST全局变量中,其它情况PHP都忽略。而php://input除了在数据类型为multipart/form-data之外为空外,其它情况都可能不为空。通过这一节,我们更加明白了php://input与$_POST的区别与联系。所以,再次确认,php://input无法读取enctype=multipart/form-data数据,当php://input遇到它时,永远为空,即便http entity body有数据。
php://input VS $http_raw_post_data
相信大家对php://input已经有一定深度地了解了。那么$http_raw_post_data是什么呢?$http_raw_post_data是PHP内置的一个全局变量。它用于,PHP在无法识别的Content-Type的情况下,将POST过来的数据原样地填入变量$http_raw_post_data。它同样无法读取Content-Type为multipart/form-data的POST数据。需要设置php.ini中的always_populate_raw_post_data值为On,PHP才会总把POST数据填入变量$http_raw_post_data。
把脚本phpinput_server.php改变一下,可以验证上述内容
@php phpinput_post.php
@php phpinput_get.php
@php phpinput_xmlrpc.php
如下:
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 04:07:52 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 6
Connection: close
Content-Type: text/html; charset=utf-8
0
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 04:07:59 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 6
Connection: close
Content-Type: text/html; charset=utf-8
1
HTTP/1.1 200 OK
Date: Fri, 22 Jul 2011 04:08:26 GMT
Server: Apache/2.0.59 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Vary: Accept-Encoding
Content-Length: 6
Connection: close
Content-Type: text/html; charset=utf-8
1
得出的结果输出都是一样的,即都为1,表示php://input和$HTTP_RAW_POST_DATA是相同的。至于对内存的压力,我们这里就不做细致地测试了。有兴趣的,可以通过xhprof进行测试和观察。
以此,我们这节可以总结如下:
1, php://input 可以读取http entity body中指定长度的值,由Content-Length指定长度,不管是POST方式或者GET方法提交过来的数据。但是,一般GET方法提交数据时,http request entity body部分都为空。
2,php://input 与$HTTP_RAW_POST_DATA读取的数据是一样的,都只读取Content-Type不为multipart/form-data的数据。
学习笔记
1,Coentent-Type仅在取值为application/x-www-data-urlencoded和multipart/form-data两种情况下,PHP才会将http请求数据包中相应的数据填入全局变量$_POST
2,PHP不能识别的Content-Type类型的时候,会将http请求包中相应的数据填入变量$HTTP_RAW_POST_DATA
3, 只有Coentent-Type不为multipart/form-data的时候,PHP不会将http请求数据包中的相应数据填入php://input,否则其它情况都会。填入的长度,由Coentent-Length指定。
4,只有Content-Type为application/x-www-data-urlencoded时,php://input数据才跟$_POST数据相一致。
5,php://input数据总是跟$HTTP_RAW_POST_DATA相同,但是php://input比$HTTP_RAW_POST_DATA更凑效,且不需要特殊设置php.ini
6,PHP会将PATH字段的query_path部分,填入全局变量$_GET。通常情况下,GET方法提交的http请求,body为空。
Araxis.Merge比较合并工具,推荐安装,比TSVN内置的TMerge好,安装Araxis.Merge后,可使用Araxis.Merge代替内置TortoiseSVN比对工具,可以更直观方便的进行SVN版本比较和冲突处理。
比对合并工具软件Araxis.Merge(必须设置)
从安装目录解压并安装Araxis.Merge后,可使用Araxis.Merge代替内置TortoiseSVN比对工具,可以更直观方便的进行SVN版本比较和冲突处理。
TortoiseSVN――Setting――External Programs――
(1) Diff Viewer (用于版本比较)
选External单选按钮
在下面填入
"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe" %base %mine
其中"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe"为Araxis.Merge程序的安装路径
我的配置:
(2) Merge Tool (用于版本合并冲突处理)
选External单选按钮
在下面填入:
"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe" %theirs %merged %mine其中"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe"为Araxis.Merge程序的安装路径
我的配置:
注:Araxis Merge启动后,可以先点击界面上第二排工具栏中,第三个图标“自动合并到中间(原型)文件”,会自动弹出提示有几个冲突,并把冲突高亮出来,以免修正时漏掉。
有一个哥们写的合并svn冲突的例子放这儿:
下载文件
比对合并工具软件Araxis.Merge(必须设置)
从安装目录解压并安装Araxis.Merge后,可使用Araxis.Merge代替内置TortoiseSVN比对工具,可以更直观方便的进行SVN版本比较和冲突处理。
TortoiseSVN――Setting――External Programs――
(1) Diff Viewer (用于版本比较)
选External单选按钮
在下面填入
"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe" %base %mine
其中"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe"为Araxis.Merge程序的安装路径
我的配置:
(2) Merge Tool (用于版本合并冲突处理)
选External单选按钮
在下面填入:
"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe" %theirs %merged %mine其中"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe"为Araxis.Merge程序的安装路径
我的配置:
注:Araxis Merge启动后,可以先点击界面上第二排工具栏中,第三个图标“自动合并到中间(原型)文件”,会自动弹出提示有几个冲突,并把冲突高亮出来,以免修正时漏掉。
有一个哥们写的合并svn冲突的例子放这儿:

[个人原创]su与sudo、su - root的区别在工作环境和附带的可执行文件.bashrc
Unix/LinuxC技术 jackxiang 2011-7-12 18:46
su 和 sudo 的区别:
1.共同点:都是root用户的权限;
2.不同点:su仅仅取得root权限,工作环境不变,还是在切换之前用户的工作环境;sudo是完全取得root的权限和root的工作环境。
su - root 和 su root(su)有什么区别?
su - root:表示人以root身份登录
just like login as root, then the shell is login shell,
which mean it will expericene a login process,
usually .bash_profile and .bashrc will be sourced
su root:表示与root建立一个链接,通过root执行命令
like you open an interactive shell in root name,
最直接的区别就是su目录还是原先用户的目录
但是su或su - root后目录就变为root用户的主目录了。
实践:
vi /root/.bashrc
我是先root登录后:
root@172.25.3*.7*:~# su jackxiang
jackxiang@Tencent:/root>
发现上面的区别了吧?由root变为jackxiang后,控制台出现不同,再来看看:
jackxiang@Tencent:/root> cdh
bash: cdh: command not found
cdh这个不存在,也就是/root/.bashrc这个没有被执行,注意这点。
我们再 su - root 一下:
看上面,控制台变了吧,主要原因是什么呢?是因为我们在su - root,或者su root 时,这一瞬间其root时去执行了脚本:
/root/.bashrc。
它告诉我们,想要修改PATH,PHP,APACHE,Mysql等的路径,都可以到这个脚本中添加即可。
有一个文档说明此事:
下载文件
1.共同点:都是root用户的权限;
2.不同点:su仅仅取得root权限,工作环境不变,还是在切换之前用户的工作环境;sudo是完全取得root的权限和root的工作环境。
su - root 和 su root(su)有什么区别?
su - root:表示人以root身份登录
just like login as root, then the shell is login shell,
which mean it will expericene a login process,
usually .bash_profile and .bashrc will be sourced
su root:表示与root建立一个链接,通过root执行命令
like you open an interactive shell in root name,
最直接的区别就是su目录还是原先用户的目录
但是su或su - root后目录就变为root用户的主目录了。
实践:
vi /root/.bashrc
我是先root登录后:
root@172.25.3*.7*:~# su jackxiang
jackxiang@Tencent:/root>
发现上面的区别了吧?由root变为jackxiang后,控制台出现不同,再来看看:
jackxiang@Tencent:/root> cdh
bash: cdh: command not found
cdh这个不存在,也就是/root/.bashrc这个没有被执行,注意这点。
我们再 su - root 一下:
看上面,控制台变了吧,主要原因是什么呢?是因为我们在su - root,或者su root 时,这一瞬间其root时去执行了脚本:
/root/.bashrc。
它告诉我们,想要修改PATH,PHP,APACHE,Mysql等的路径,都可以到这个脚本中添加即可。
有一个文档说明此事:

主要是对我的个人博客的PHP执行代码进行Cache,对于Js,CSS直接在客户端缓存即可,这儿重点是对PHP的CGI执行结果在服务器端进行缓存,以减少服务器的DB查询压力,这样DB从21次/秒降低到13次/秒。目前让nginx的proxy_store和proxy_cache支持ctrl+f5和PURGE结合删除缓存的方法二种:
一.让ngx_cache_purge来帮忙,通过Nginx对ctrl+f5的标志来进行重写清除日志。
二.用PHP来实现清除后并再次跳转到对应的Uri模块,以实现页面缓存更新后的显示。
三.修改ngx_cache_purge源代码。。。。:(暂时忽略。
阅读全文
一.让ngx_cache_purge来帮忙,通过Nginx对ctrl+f5的标志来进行重写清除日志。
二.用PHP来实现清除后并再次跳转到对应的Uri模块,以实现页面缓存更新后的显示。
三.修改ngx_cache_purge源代码。。。。:(暂时忽略。

有时我们常常遇到PHP内存不足的情况,主要是做大运算,大视频图片读取及其传输等。下面是一个很方便快捷的解决方法:
两个项目:
一个是图像处理,其中一个步骤需要将原图片放大三倍,结果页面一片空白什么都没有显示
一个是使用FPDF生成PDF文件,在加载字体文件的时候默默的罢工
以上两个问题最终都发现是由于默认的PHP内存分配不足所致
PHP为防止编写不良的脚本无休止的申请内存,对每个脚本在执行期间所能申请的内存最大值都有限制,这一般是写在php.ini文件内。一般而言只需要修改此配置文件,将数值改大一些就可以解决问题。而如果使用虚拟空间或者是没有修改配置文件的权限,就只能从PHP上想办法。下面这条语句就是解决这个问题的。
ini_set("memory_limit","10M");
上句可以将本次脚本执行时所能申请的内存最大值改为10M,如果想可以无限申请内存,语句如下:
ini_set("memory_limit","-1");
这样的设置将仅仅影响被设置的脚本。一旦脚本执行完毕,该配置将自动恢复到原始值
来源:http://hi.baidu.com/dreamtonk/blog/item/320318fc0cff8853d7887d86.html
深入理解PHP内存管理之谁动了我的内存:
http://www.laruence.com/2011/03/04/1894.html
两个项目:
一个是图像处理,其中一个步骤需要将原图片放大三倍,结果页面一片空白什么都没有显示
一个是使用FPDF生成PDF文件,在加载字体文件的时候默默的罢工
以上两个问题最终都发现是由于默认的PHP内存分配不足所致
PHP为防止编写不良的脚本无休止的申请内存,对每个脚本在执行期间所能申请的内存最大值都有限制,这一般是写在php.ini文件内。一般而言只需要修改此配置文件,将数值改大一些就可以解决问题。而如果使用虚拟空间或者是没有修改配置文件的权限,就只能从PHP上想办法。下面这条语句就是解决这个问题的。
ini_set("memory_limit","10M");
上句可以将本次脚本执行时所能申请的内存最大值改为10M,如果想可以无限申请内存,语句如下:
ini_set("memory_limit","-1");
这样的设置将仅仅影响被设置的脚本。一旦脚本执行完毕,该配置将自动恢复到原始值
来源:http://hi.baidu.com/dreamtonk/blog/item/320318fc0cff8853d7887d86.html
深入理解PHP内存管理之谁动了我的内存:
http://www.laruence.com/2011/03/04/1894.html
单引号和双引号的区别和效率问题,但还是很多朋友包括本人了解的不是很清楚,一直以为PHP中单引号和双引号是互通的,到有一天,发现单引号和双引号出现错误的时候才去学习研究。所以今天再拿出来谈谈他们的区别,希望大家不要再为此困惑。
” ” 双引号里面的字段会经过编译器解释,然后再当作HTML代码输出。
阅读全文
” ” 双引号里面的字段会经过编译器解释,然后再当作HTML代码输出。

一直搞不明白三者区别,今天写下。
htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体。
预定义的字符是:
& (和号) 成为 &
" (双引号) 成为 "
' (单引号) 成为 '
< (小于) 成为 <
> (大于) 成为 >
addslashes() 函数在指定的预定义字符前添加反斜杠。
这些预定义字符是:
单引号 (')
双引号 (")
反斜杠 (\)
NULL
Who's John Adams? This is not safe in a database query.
Who\'s John Adams? This is safe in a database query.
strip_tags() 函数剥去 HTML、XML 以及 PHP 的标签。
即不带任何的标记,转换成字符串。
strip_tags(string,allow)
参数 描述
string 必需。规定要检查的字符串。
allow 可选。规定允许的标签。这些标签不会被删除
htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体。
预定义的字符是:
& (和号) 成为 &
" (双引号) 成为 "
' (单引号) 成为 '
< (小于) 成为 <
> (大于) 成为 >
addslashes() 函数在指定的预定义字符前添加反斜杠。
这些预定义字符是:
单引号 (')
双引号 (")
反斜杠 (\)
NULL
Who's John Adams? This is not safe in a database query.
Who\'s John Adams? This is safe in a database query.
strip_tags() 函数剥去 HTML、XML 以及 PHP 的标签。
即不带任何的标记,转换成字符串。
strip_tags(string,allow)
参数 描述
string 必需。规定要检查的字符串。
allow 可选。规定允许的标签。这些标签不会被删除
[个人原创]Curl模拟Host和Ip对应关系实现POST和GET请求,不用设置Host文件也可直接访问对应的虚拟机和IP对应位置。以及如何模拟客户端IP的方法。
Unix/LinuxC技术 jackxiang 2011-7-1 19:56
背景:http://jackxiang.com/post/2656/ 里有通过php进行curl配置并进行模拟IP来进行请求:PHP的curl扩展为我们用了CURLOPT_HTTPHEADER来做host的工作, curl -l -H "Host:test3.qq.com" http://17.2*.*.70/index.php,这儿讲一下用shell下的curl来一行进行模拟及其用wireshark进行抓包发现其http的头的原理。自己之前写过放在这儿:jackxiang.com/post/2656/
____________实践有用的Curl强大功能________________
用Curl直接模拟Host方法,Curl伪造Refer的方法:
http://jackxiang.com/post/6201/
获取cookie后,模拟refer并带上cookie通过curl访问某个接口:
http://jackxiang.com/post/4082/
PHP用CURL伪造IP和来源:
http://jackxiang.com/post/6201/
______________________________________________
参考:http://get.ftqq.com/9091.get
完整示例只传入data,其它项默认即可:
调用示例:
实现GET请求成功,注意 header是数组,参考来自:http://get.ftqq.com/9091.get ,关于Host: xxx.xx.com在Header里是数组,否则会报警告:
第三行改为
$header[] = "Content-type: text/xml"; // 改为数组解决
配置文件:
'SETEGGSHOST' => 'Host: wx.xxx.com',
'SETEGGSHTTP' => 'http://%s/Api/Eggs/Eggs/doSetTemp',
'SETEGGSPARA' => 'eid=%s&temp=%s&humi=%s',
最后,Host: wx.xx.com =数组传入=》 $setEggsHostArr = array(Config::getInstance()->getConf('SETEGGSHOST'));得注意。
Host: wx.xx.com eid=83419527&temp=38.2&humi=45 http://wx.xx.com/Api/Eggs/Eggs/doSetTempbool
—————————————————————Curl模拟Host和Ip对应关系—————————————————————
一个是Linux命令行来实现,二是从PHP编码上来实现不用修改Linux的Host就可能实现对虚拟主机的访问,实现如下:
一.假如70上有一个test3.qq.com ,我们在Windows下还需要通过
对Host加入配置:
后,
才能通过浏览器访问,而我们如果不加就不能访问。
现在,可以通过Curl来不用修改host文件也能访问,如下:
去Host:
用Curl直接模拟Host如下:
如果看代码图片:
curl -l -H "Host:mytv.jackxiang.com" http://127.0.0.1/uploads/temp/201310261334109440.jpg > xdy.jpg
-----------------------------------------------------------------------------------------------------------------------------------------------------------
如果有&号连接的Url需要对Url加引号:
curl -l --silent -v -H "Host:api.xdxp.cn" "http://115.182.35.108/general/getVideoCategoryList?uid=100&videoCategoryIds=15,16,17,18,19,20,31&format=json"
* Trying 115.182.35.108... connected
* Connected to 115.182.35.108 (115.182.35.108) port 80 (#0)
> GET /general/getVideoCategoryList?uid=100&videoCategoryIds=15,16,17,18,19,20,31&format=json HTTP/1.1
不加引号的情况:
curl -l --silent -v -H "Host:api.xdxp.cn" http://115.182.35.108/general/getVideoCategoryList?uid=100&videoCategoryIds=15,16,17,18,19,20,31&format=json
* About to connect() to 115.182.35.108 port 80 (#0)
* Trying 115.182.35.108... connected
* Connected to 115.182.35.108 (115.182.35.108) port 80 (#0)
> GET /general/getVideoCategoryList?uid=100 HTTP/1.1
-----------------------------------------------------------------------------------------------------------------------------------------------------------
与此同时,我们还能通过在Linux自己带的Curl来进行不用设置/etc/hosts来实现我们自己的模拟host访问。这样在调试接口等就不用我们自己每次都修改Host文件了,带来了极大的方便。
二.我们在PHP代码编程使用中PHP设置Curl参数来实现的代码片段如下,注意传入的是IP,而Host设置在函数的代码中:
如一个域名有两个IP,如何来实现调用的简单实现,这样有利于分担接口负载,如下:
综上所述,其本质是模拟了Http协议的头,想了解更多请看我之前写的一篇文章:
《PHP CURL CURLOPT_HTTPHEADER设置HOST(也就是不用配置host访问),Curl伪造Refer的方法及其杂谈》
Url:http://jackxiang.com/post/4022/
—————————————————————伪造客户端IP—————————————————————
一)这就是伪造的Curl的PHP代码:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:'.$sendip, 'CLIENT-IP:'.$sendip));
来自:http://www.phpec.org/php/curl.html
参考:http://www.onlypo.com/archives/7
二)在Linux的Shell环境下如何不用PHP设置Header呢?
linux curl http header处理:
设置http请求头信息:
curl -A "Mozilla/5.0 Firefox/21.0" http://www.baidu.com #设置http请求头User-Agent
curl -e "http://pachong.org/" http://www.baidu.com #设置http请求头Referer
curl -H "Connection:keep-alive \n User-Agent: Mozilla/5.0" http://www.aiezu.com
来自:http://www.aiezu.com/system/linux/linux_curl_syntax.html
于是,如果忽悠下服务器端简单获取客户端的IP,实践如下,用-H参数即可:
于是日志显示:2013/12/06 21:05:57 HostIp:jackxiang.com--ClientIp:192.168.1.108--
果然被curl给忽悠了吧,其被忽悠的代码如下:
X-Forwarded-For:192.168.1.108 在http头里通过linux下的curl注入头里即可!
调用如下:
file_put_contents($logFile, date("Y/m/d H:i:s") . "\t" . $type .'HostIp:'.$this->request->getHttpHost().'--'.'ClientIp:'.$this->request->getClientIp().'--'. "\t" . var_export($msg, true) . "\n", FILE_APPEND);
代码片段如下:
模拟修改Host的IP,不用修改Host文件的方法也是-H参数,能否合并起来使用呢?实践是不行的,如下探讨研究:
但是把上面两个写在一块用\n分开,实践好像不行,尽管上面有这样一个示例:
curl -H "Connection:keep-alive \n User-Agent: Mozilla/5.0" http://www.aiezu.com
实践是可行的,如:curl -H "Connection:keep-alive \n User-Agent: Mozilla/5.0" http://www.baidu.com
Connection:keep-alive \n User-Agent: Mozilla/5.0
但是把Curl模拟Host所对IP及如模拟客户端IP放一块,实践不Ok,如下:
出现接口返回不对,Nginx如下,只能单用吗?疑惑,因为这都是\r\n拼接的呀,\r\n也不行,如:http://www.myhack58.com/Article/html/3/62/2012/34944_2.htm
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
很有可能是一个要非ip的字母数字作为域名,而另一个是要ip冲突导致矛盾吧?
Add Time:2013-12-19
在实践中用到,一外包兄弟写的代码经过队列调时出现没有入库,但是线上有多台机器,而所配置的机器的/etc/hosts指向是虚拟IP,不能修改,于是否,用这个方法找到了问题所在,其双方沟通的接口参数不一致导致,当时是怎么说通了,这个真是玄乎,代码如下:
对下面这个链接进行tcpdump抓包查看其请求是怎么样的,这儿python主要是想对json输出不能轻易读取加上json输出一行进行格式化:
第一点:直接用ip访问就不用找dns了,直接对IP访问,这是一定的。
第二点:这个-H主要体现在头上,也就是服务器(如:WebServer nginx apache tomcat都是对这个解析进行分发到或是php-fpm进行解析这个头作返回)
User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
Accept: */*
Host:t43.jackxiang.com
也就是说,根据nginx里的conf文件进行分发时核对Host,或是php-fpm进行分发,这块还需要进一步研究,自己写server时可能会用到,也就这儿可以作为标志,至于怎么去的,我们可以直接用域名作对比:
1)域名直接访问(会先读host或dns得到一个ip后直接对其发起连接),curl "http://t43.jackxiang.com/json.php":
Source Destination Protocol
192.168.131.6 115.182.9.243 HTTP
GET /json.php HTTP/1.1
User-Agent: curl/7.17.0 (i586-pc-mingw32msvc) libcurl/7.17.0 zlib/1.2.2
Host: t43.jackxiang.com
Accept: */*
附:curl -H"Host:t43.jackxiang.com" "http://115.182.9.243/json.php"
2)用-H的curl通过localhost进行访问:
Source Destination Protocol
127.0.0.1 127.0.0.1 HTTP
User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
Accept: */*
Host:t43.jackxiang.com
直接访问IP是不行的,加一个错误的头也是不行的,说明的的确确是这个Host:xxx进行解析:
C:\>curl -H"t43.jackxiang.com" "http://115.182.9.243/json.php"
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
C:\>curl -H"Host:t43.jackxiang.com" "http://115.182.9.243/json.php"
{ "status":200, "data": [ { "id":1000, "name":"John" }, { "id":1004
, "name":"Tom" } ] }
____________实践有用的Curl强大功能________________
用Curl直接模拟Host方法,Curl伪造Refer的方法:
http://jackxiang.com/post/6201/
获取cookie后,模拟refer并带上cookie通过curl访问某个接口:
http://jackxiang.com/post/4082/
PHP用CURL伪造IP和来源:
http://jackxiang.com/post/6201/
______________________________________________
参考:http://get.ftqq.com/9091.get
完整示例只传入data,其它项默认即可:
调用示例:
实现GET请求成功,注意 header是数组,参考来自:http://get.ftqq.com/9091.get ,关于Host: xxx.xx.com在Header里是数组,否则会报警告:
第三行改为
$header[] = "Content-type: text/xml"; // 改为数组解决
配置文件:
'SETEGGSHOST' => 'Host: wx.xxx.com',
'SETEGGSHTTP' => 'http://%s/Api/Eggs/Eggs/doSetTemp',
'SETEGGSPARA' => 'eid=%s&temp=%s&humi=%s',
最后,Host: wx.xx.com =数组传入=》 $setEggsHostArr = array(Config::getInstance()->getConf('SETEGGSHOST'));得注意。
Host: wx.xx.com eid=83419527&temp=38.2&humi=45 http://wx.xx.com/Api/Eggs/Eggs/doSetTempbool
—————————————————————Curl模拟Host和Ip对应关系—————————————————————
一个是Linux命令行来实现,二是从PHP编码上来实现不用修改Linux的Host就可能实现对虚拟主机的访问,实现如下:
一.假如70上有一个test3.qq.com ,我们在Windows下还需要通过
对Host加入配置:
后,
才能通过浏览器访问,而我们如果不加就不能访问。
现在,可以通过Curl来不用修改host文件也能访问,如下:
去Host:
用Curl直接模拟Host如下:
如果看代码图片:
curl -l -H "Host:mytv.jackxiang.com" http://127.0.0.1/uploads/temp/201310261334109440.jpg > xdy.jpg
-----------------------------------------------------------------------------------------------------------------------------------------------------------
如果有&号连接的Url需要对Url加引号:
curl -l --silent -v -H "Host:api.xdxp.cn" "http://115.182.35.108/general/getVideoCategoryList?uid=100&videoCategoryIds=15,16,17,18,19,20,31&format=json"
* Trying 115.182.35.108... connected
* Connected to 115.182.35.108 (115.182.35.108) port 80 (#0)
> GET /general/getVideoCategoryList?uid=100&videoCategoryIds=15,16,17,18,19,20,31&format=json HTTP/1.1
不加引号的情况:
curl -l --silent -v -H "Host:api.xdxp.cn" http://115.182.35.108/general/getVideoCategoryList?uid=100&videoCategoryIds=15,16,17,18,19,20,31&format=json
* About to connect() to 115.182.35.108 port 80 (#0)
* Trying 115.182.35.108... connected
* Connected to 115.182.35.108 (115.182.35.108) port 80 (#0)
> GET /general/getVideoCategoryList?uid=100 HTTP/1.1
-----------------------------------------------------------------------------------------------------------------------------------------------------------
与此同时,我们还能通过在Linux自己带的Curl来进行不用设置/etc/hosts来实现我们自己的模拟host访问。这样在调试接口等就不用我们自己每次都修改Host文件了,带来了极大的方便。
二.我们在PHP代码编程使用中PHP设置Curl参数来实现的代码片段如下,注意传入的是IP,而Host设置在函数的代码中:
如一个域名有两个IP,如何来实现调用的简单实现,这样有利于分担接口负载,如下:
综上所述,其本质是模拟了Http协议的头,想了解更多请看我之前写的一篇文章:
《PHP CURL CURLOPT_HTTPHEADER设置HOST(也就是不用配置host访问),Curl伪造Refer的方法及其杂谈》
Url:http://jackxiang.com/post/4022/
—————————————————————伪造客户端IP—————————————————————
一)这就是伪造的Curl的PHP代码:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:'.$sendip, 'CLIENT-IP:'.$sendip));
来自:http://www.phpec.org/php/curl.html
参考:http://www.onlypo.com/archives/7
二)在Linux的Shell环境下如何不用PHP设置Header呢?
linux curl http header处理:
设置http请求头信息:
curl -A "Mozilla/5.0 Firefox/21.0" http://www.baidu.com #设置http请求头User-Agent
curl -e "http://pachong.org/" http://www.baidu.com #设置http请求头Referer
curl -H "Connection:keep-alive \n User-Agent: Mozilla/5.0" http://www.aiezu.com
来自:http://www.aiezu.com/system/linux/linux_curl_syntax.html
于是,如果忽悠下服务器端简单获取客户端的IP,实践如下,用-H参数即可:
于是日志显示:2013/12/06 21:05:57 HostIp:jackxiang.com--ClientIp:192.168.1.108--
果然被curl给忽悠了吧,其被忽悠的代码如下:
X-Forwarded-For:192.168.1.108 在http头里通过linux下的curl注入头里即可!
调用如下:
file_put_contents($logFile, date("Y/m/d H:i:s") . "\t" . $type .'HostIp:'.$this->request->getHttpHost().'--'.'ClientIp:'.$this->request->getClientIp().'--'. "\t" . var_export($msg, true) . "\n", FILE_APPEND);
代码片段如下:
模拟修改Host的IP,不用修改Host文件的方法也是-H参数,能否合并起来使用呢?实践是不行的,如下探讨研究:
但是把上面两个写在一块用\n分开,实践好像不行,尽管上面有这样一个示例:
curl -H "Connection:keep-alive \n User-Agent: Mozilla/5.0" http://www.aiezu.com
实践是可行的,如:curl -H "Connection:keep-alive \n User-Agent: Mozilla/5.0" http://www.baidu.com
Connection:keep-alive \n User-Agent: Mozilla/5.0
但是把Curl模拟Host所对IP及如模拟客户端IP放一块,实践不Ok,如下:
出现接口返回不对,Nginx如下,只能单用吗?疑惑,因为这都是\r\n拼接的呀,\r\n也不行,如:http://www.myhack58.com/Article/html/3/62/2012/34944_2.htm
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
很有可能是一个要非ip的字母数字作为域名,而另一个是要ip冲突导致矛盾吧?
Add Time:2013-12-19
在实践中用到,一外包兄弟写的代码经过队列调时出现没有入库,但是线上有多台机器,而所配置的机器的/etc/hosts指向是虚拟IP,不能修改,于是否,用这个方法找到了问题所在,其双方沟通的接口参数不一致导致,当时是怎么说通了,这个真是玄乎,代码如下:
对下面这个链接进行tcpdump抓包查看其请求是怎么样的,这儿python主要是想对json输出不能轻易读取加上json输出一行进行格式化:
第一点:直接用ip访问就不用找dns了,直接对IP访问,这是一定的。
第二点:这个-H主要体现在头上,也就是服务器(如:WebServer nginx apache tomcat都是对这个解析进行分发到或是php-fpm进行解析这个头作返回)
User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
Accept: */*
Host:t43.jackxiang.com
也就是说,根据nginx里的conf文件进行分发时核对Host,或是php-fpm进行分发,这块还需要进一步研究,自己写server时可能会用到,也就这儿可以作为标志,至于怎么去的,我们可以直接用域名作对比:
1)域名直接访问(会先读host或dns得到一个ip后直接对其发起连接),curl "http://t43.jackxiang.com/json.php":
Source Destination Protocol
192.168.131.6 115.182.9.243 HTTP
GET /json.php HTTP/1.1
User-Agent: curl/7.17.0 (i586-pc-mingw32msvc) libcurl/7.17.0 zlib/1.2.2
Host: t43.jackxiang.com
Accept: */*
附:curl -H"Host:t43.jackxiang.com" "http://115.182.9.243/json.php"
2)用-H的curl通过localhost进行访问:
Source Destination Protocol
127.0.0.1 127.0.0.1 HTTP
User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
Accept: */*
Host:t43.jackxiang.com
直接访问IP是不行的,加一个错误的头也是不行的,说明的的确确是这个Host:xxx进行解析:
C:\>curl -H"t43.jackxiang.com" "http://115.182.9.243/json.php"
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
C:\>curl -H"Host:t43.jackxiang.com" "http://115.182.9.243/json.php"
{ "status":200, "data": [ { "id":1000, "name":"John" }, { "id":1004
, "name":"Tom" } ] }
[个人原创]用firebug调试JS时,利用其单步进入功能分析多层嵌套函数后能快速找到多层函数原型所在的文件名的方法
Php/Js/Shell/Go jackxiang 2011-6-30 23:40
现在你想看函数里的变量和值,你只需要在js里某个地输入:debugger; 即可,否则,你要想看变量是不可能的,或者加断点也成。
断点继续运行:F8
单步进入嵌套调用的函数体实现内部:F11
单步跳过:F10
单步退出:Shift+F11
从知道函数入口的函数中嵌套的函数在另外一个文件,可以通过单步进入查看进入后,就能知道另外一个文件的Js文件的名称,知道文件名后是快速解决Js问题的基础,如下图:

阅读全文
断点继续运行:F8
单步进入嵌套调用的函数体实现内部:F11
单步跳过:F10
单步退出:Shift+F11
从知道函数入口的函数中嵌套的函数在另外一个文件,可以通过单步进入查看进入后,就能知道另外一个文件的Js文件的名称,知道文件名后是快速解决Js问题的基础,如下图:

[个人原创]使用PHP的Socket来模拟RFC协议中的网页POST上传图片
Php/Js/Shell/Go jackxiang 2011-6-25 20:08
content-length: 这个值是从--$boundary,\r\nContent-Disposition: form-data; name=\"".rawurlencode($k)."\"\r\n\r\n, ...文件内容。。。\r\n".$boundary_2."--\r\n\r\n结束。注意:
最后的content的分割符也就是boundary还有两个--,表示结束。
其实协议是一个规化,代码是一个实现,久而久之,规划成为了规则,如:RFC协议就是一个大家在开发浏览器必须遵守的协议(http的(RFC 1867):让HTML表单可以提交文件。它对HTML表单的扩展),而也具有开放性,为此,各种程序都可以实现这个协议,程序为协议而生,协议为功能而用,下面我们来实现一个通过PHP的Socket来模拟一次浏览器上传一张图片的提交代码,如下:
模拟浏览器遵循的Http协议发送图片程序,boundary开始时有一个 --,结束时:也有有 --,真正结束后有\r\n\r\n:
PHP接收发送过来的图片程序:
测试返回:
为何出现这样的情况呢?查找代码片段imageaaa,这个修改为file即可,修改后如下所示,上传成功:
说明是Ok的,查下upload目录下,果然是在这个图片的,证明PHP是完全可以通过fsocket来模拟Http上传图片协议来实现浏览器上传的。
阅读全文
最后的content的分割符也就是boundary还有两个--,表示结束。
其实协议是一个规化,代码是一个实现,久而久之,规划成为了规则,如:RFC协议就是一个大家在开发浏览器必须遵守的协议(http的(RFC 1867):让HTML表单可以提交文件。它对HTML表单的扩展),而也具有开放性,为此,各种程序都可以实现这个协议,程序为协议而生,协议为功能而用,下面我们来实现一个通过PHP的Socket来模拟一次浏览器上传一张图片的提交代码,如下:
模拟浏览器遵循的Http协议发送图片程序,boundary开始时有一个 --,结束时:也有有 --,真正结束后有\r\n\r\n:
PHP接收发送过来的图片程序:
测试返回:
为何出现这样的情况呢?查找代码片段imageaaa,这个修改为file即可,修改后如下所示,上传成功:
说明是Ok的,查下upload目录下,果然是在这个图片的,证明PHP是完全可以通过fsocket来模拟Http上传图片协议来实现浏览器上传的。

打乱1~10000这个数组,然后取前200
C 语言不像 PHP/Python 等动态语言, 可以无缝地将 JSON 数据结构转为自身的数据结构, 所以操作起来会有些麻烦.
来源:http://www.ideawu.net/blog/2010/08/c%E8%AF%AD%E8%A8%80%E8%A7%A3%E6%9E%90json.html
阅读全文
来源:http://www.ideawu.net/blog/2010/08/c%E8%AF%AD%E8%A8%80%E8%A7%A3%E6%9E%90json.html

由于一段时间服务器负载较重,占用了2g的虚拟内存。这段时间过后,在不重启机器的情况下如何将这2g的虚拟内存释放出来?
用vmstat查看虚拟内存使用量swpd 就是交换的虚拟内存:
我的办法就是:
root@darkstar:~# vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 264 986380 323224 156860 0 0 0 0 0 0 0 0 100 0
root@darkstar:~# swapoff -a
root@darkstar:~# vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 986752 323240 157240 0 0 0 0 0 0 0 0 100 0
root@darkstar:~# swapon -a
root@darkstar:~# vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 986652 323292 157188 0 0 0 0 0 0 0 0 100 0
Windows下释放虚拟内存的方法:
右键单击“我的电脑”--“属性”—“高级”,在“性能”栏中,点击“设置”—“高级”—将“处理器计划”、“内存使用”,均点选“程序”。 单击“虚拟内存”区“更改”--在驱动器列表中选中系统盘符--自定义大小--在“初始大小”和“最大值”中设定数值,然后单击“设置”按钮,最后点击“确定”按钮退出。虚拟内存最小值物理内存1.5—2倍,最大值为物理内存的2—3倍。
来源:http://bbs.chinaunix.net/thread-2052543-1-1.html
来源2:http://wenwen.soso.com/z/q141265413.htm
用vmstat查看虚拟内存使用量swpd 就是交换的虚拟内存:
我的办法就是:
root@darkstar:~# vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 264 986380 323224 156860 0 0 0 0 0 0 0 0 100 0
root@darkstar:~# swapoff -a
root@darkstar:~# vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 986752 323240 157240 0 0 0 0 0 0 0 0 100 0
root@darkstar:~# swapon -a
root@darkstar:~# vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 986652 323292 157188 0 0 0 0 0 0 0 0 100 0
Windows下释放虚拟内存的方法:
右键单击“我的电脑”--“属性”—“高级”,在“性能”栏中,点击“设置”—“高级”—将“处理器计划”、“内存使用”,均点选“程序”。 单击“虚拟内存”区“更改”--在驱动器列表中选中系统盘符--自定义大小--在“初始大小”和“最大值”中设定数值,然后单击“设置”按钮,最后点击“确定”按钮退出。虚拟内存最小值物理内存1.5—2倍,最大值为物理内存的2—3倍。
来源:http://bbs.chinaunix.net/thread-2052543-1-1.html
来源2:http://wenwen.soso.com/z/q141265413.htm
我暂时还不清楚 HTTP 文件上传的具体细节, 但是我知道通过浏览器上传文件, 然后用 PHP 接收, 需要使用 PHP 的预定义变量 $_FILES. 最近我有一个应用需要使用 PHP 的预定义变量 $_POST 获取上传的文件(或者任何数据), 也就是通过 HTTP POST 参数传递二进制数据.
工作在 ContentType = “application/x-www-form-urlencoded” 的模式下时, HTTP 协议使用 ASCII 字符集的一个子集来编码要传输的字节流. 如字符串 “a@” 如果以 ASCII 编码存在于内存中(以字节数组的形式), 也就是内存按字节读取为 HEX 是: 0×61 0×40, 那么该字节数组被传输时会被编码(URL 编码)成为 0×61 0×25 0×34 0×30, 被编码后字节数组如果按照 ASCII 编码显示, 就是 “a%40″. 也就是说, 当你想传输 0×61 0×40 时, HTTP 传输的是 0×61 0×25 0×34 0×30.
这种编码过程几乎所有的编程语言都提供支持, 在 C# 中你可以使用 HttpUtility.UrlEncode(), 输入一个字节数组, 返回一个 URL 编码的 字节数组.
在 PHP 脚本中, 当你使用 $_POST['data'] 获取数组时, 该数组已经被 PHP 自动解码了. 按照上面的例子, $_POST['data'] 所指向的内存内容为 0×61 0×40 — 但是, 默认情况下并不总是, 如果该数据包含单引号等少数几个字符, 那么它们的前面会被 PHP 加上 \.
下面先给出 PHP 脚本, 保存一个通过 HTTP 参数传递的文件:
如果你要测试的文件小于 8K, 可以直接使用上面的程序测试. 如果大于, 你可以加大 buffer 的容量.
上传成功后, 使用文件比较工具对比两个文件是否一致:
diff test.jpg up_test.jpg
这种方式的典型的应用是自定义文件上传, 你只需要更改少量的代码就可以实现支持断点续传功能的文件上传.
来源:http://www.ideawu.net/blog/2007/08/%E9%80%9A%E8%BF%87-HTTP-POST-%E5%8F%91%E9%80%81%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%95%B0%E6%8D%AE.html
工作在 ContentType = “application/x-www-form-urlencoded” 的模式下时, HTTP 协议使用 ASCII 字符集的一个子集来编码要传输的字节流. 如字符串 “a@” 如果以 ASCII 编码存在于内存中(以字节数组的形式), 也就是内存按字节读取为 HEX 是: 0×61 0×40, 那么该字节数组被传输时会被编码(URL 编码)成为 0×61 0×25 0×34 0×30, 被编码后字节数组如果按照 ASCII 编码显示, 就是 “a%40″. 也就是说, 当你想传输 0×61 0×40 时, HTTP 传输的是 0×61 0×25 0×34 0×30.
这种编码过程几乎所有的编程语言都提供支持, 在 C# 中你可以使用 HttpUtility.UrlEncode(), 输入一个字节数组, 返回一个 URL 编码的 字节数组.
在 PHP 脚本中, 当你使用 $_POST['data'] 获取数组时, 该数组已经被 PHP 自动解码了. 按照上面的例子, $_POST['data'] 所指向的内存内容为 0×61 0×40 — 但是, 默认情况下并不总是, 如果该数据包含单引号等少数几个字符, 那么它们的前面会被 PHP 加上 \.
下面先给出 PHP 脚本, 保存一个通过 HTTP 参数传递的文件:
如果你要测试的文件小于 8K, 可以直接使用上面的程序测试. 如果大于, 你可以加大 buffer 的容量.
上传成功后, 使用文件比较工具对比两个文件是否一致:
diff test.jpg up_test.jpg
这种方式的典型的应用是自定义文件上传, 你只需要更改少量的代码就可以实现支持断点续传功能的文件上传.
来源:http://www.ideawu.net/blog/2007/08/%E9%80%9A%E8%BF%87-HTTP-POST-%E5%8F%91%E9%80%81%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%95%B0%E6%8D%AE.html