把下面代码贴到.vimrc文件中就行了,然后,重新打开vim,写一个函数试试,我感觉还不错的...
来源:http://phpor.net/blog/post/881/
来源:http://phpor.net/blog/post/881/
在日常生活中往往有一些命令很长,如要到apache的htdocs下,要到Mysql和Apache的下bin目录下,要删除某个文件而事实上是把这个rm -Rf 变为了移动到某个大硬盘中去了,就会避免误删除后出现找不回文件了(当然有些软件可以找回,另当别论),别名可用来定义新的命令。一条别名当多条,这些别名通常放在初始化文件~/.bashrc(bash)或者/.tcshrc(tcsh)中,这样在交互式子shell中就可以使用这些别名。
在bash中,内置命令alias的语法如下:
在tcsh中语法如下:
jackxiang@178.258.918.106:/# vi ~/.bashrc
阅读全文
在bash中,内置命令alias的语法如下:
在tcsh中语法如下:
jackxiang@178.258.918.106:/# vi ~/.bashrc
阅读全文
背景:这块一般是这样的,linux是什么用户登录就是什么用户的home下,如root用户就是/root,如果xiangdong就是/home/xiangdong。这块可以在用c语言进行切换时伪装成root,文章如下:https://jackxiang.com/post/7556/ 。
用Svn时会有一种需求是需要换个帐号测试一下什么的,但往往有缓存,于是需要清理下才行:
一搬来说在客户端清理一下即可,经过实践是Ok的,如下:
1、在项目上右键,选择TortoiseSVN-->settings,
2、在弹出的TortoiseSVN Settings页面中选择“Saved Data”选项,
3、然后点击“Authentication data”对应的“Clear”按钮,清除一下之前的认证信息就可以了。
下次,就会要求输入用户名和密码,OK!
=============下面这个没有试过==================
svn客户端取消认证缓存设置,需要两个步骤:
(1)修改配置文件,使下次登录时不记录密码
windows环境,在开始菜单->运行输入:%appdata%/subversion,找到config文件【反正自己找到即可】;
unix/linux环境,编辑~/.subversion/config文件。这个试过可以的。
分别对以下两行取消注释、然后保存退出;
# store-passwords = no
# store-auth-creds = no
(2)删除认证缓存设置
windows环境,删除:%appdata%/subversion/auth目录
unix/linux环境执行:rm -rf ~/.subversion/auth
windows 和 linux下 清除svn保存的账号密码信息:
==================================
windows下
方法1:对于TortoiseSVN软件,右键出TortoiseSVN菜单Settings->Saved Data->Authentication data,Clear
或者
方法2:C:\Documents and Settings\Administrator\Application Data\Subversion\auth
删除auth下面的所有文件夹
如果以上2个方法都不起作用,那么只能卸载TortoiseSVN,再重新安装一次,之后上面的2个方法就能起作用了.
==================================
linux下
删除~/.subversion/auth即可
luther@gliethttp:~$ rm -rf ~/.subversion/auth
#:~/.subversion/auth # ls
svn.simple svn.ssl.client-passphrase svn.ssl.server svn.username
这个文件:
./svn.simple/ff163eadbbc43c8f640a9163591xxec0:jackxiang
用Svn时会有一种需求是需要换个帐号测试一下什么的,但往往有缓存,于是需要清理下才行:
一搬来说在客户端清理一下即可,经过实践是Ok的,如下:
1、在项目上右键,选择TortoiseSVN-->settings,
2、在弹出的TortoiseSVN Settings页面中选择“Saved Data”选项,
3、然后点击“Authentication data”对应的“Clear”按钮,清除一下之前的认证信息就可以了。
下次,就会要求输入用户名和密码,OK!
=============下面这个没有试过==================
svn客户端取消认证缓存设置,需要两个步骤:
(1)修改配置文件,使下次登录时不记录密码
windows环境,在开始菜单->运行输入:%appdata%/subversion,找到config文件【反正自己找到即可】;
unix/linux环境,编辑~/.subversion/config文件。这个试过可以的。
分别对以下两行取消注释、然后保存退出;
# store-passwords = no
# store-auth-creds = no
(2)删除认证缓存设置
windows环境,删除:%appdata%/subversion/auth目录
unix/linux环境执行:rm -rf ~/.subversion/auth
windows 和 linux下 清除svn保存的账号密码信息:
==================================
windows下
方法1:对于TortoiseSVN软件,右键出TortoiseSVN菜单Settings->Saved Data->Authentication data,Clear
或者
方法2:C:\Documents and Settings\Administrator\Application Data\Subversion\auth
删除auth下面的所有文件夹
如果以上2个方法都不起作用,那么只能卸载TortoiseSVN,再重新安装一次,之后上面的2个方法就能起作用了.
==================================
linux下
删除~/.subversion/auth即可
luther@gliethttp:~$ rm -rf ~/.subversion/auth
#:~/.subversion/auth # ls
svn.simple svn.ssl.client-passphrase svn.ssl.server svn.username
这个文件:
./svn.simple/ff163eadbbc43c8f640a9163591xxec0:jackxiang
[个人原创]在某个文件的每行后追加一段相同的文本,也就是行尾追加的PHP简单实现
Php/Js/Shell/Go jackxiang 2011-8-4 14:57
在PHP的高级编程群里有位兄弟问这个问题,于是我就写一个如下:
在/tmp/a.txt后面每行追加jackxiang.com,PHP代码如下:
注意:
1. file_put_contents的第一次写和第N次写的参数不同。
2.注意file读取出来的数组中有换行符号的,需要通过str_replace去掉。
3.Linux下Win下不同的回车
最后,直接全部读取出来进行替换也可以的。
其实,这个去换行符号也是在网上找的,有两种:
第一种:
$content=str_replace("\n","",$content);
echo $content;
第二种:
$content=preg_replace("/\s/","",$content);
echo $content;
呵呵。
在/tmp/a.txt后面每行追加jackxiang.com,PHP代码如下:
注意:
1. file_put_contents的第一次写和第N次写的参数不同。
2.注意file读取出来的数组中有换行符号的,需要通过str_replace去掉。
3.Linux下Win下不同的回车
最后,直接全部读取出来进行替换也可以的。
其实,这个去换行符号也是在网上找的,有两种:
第一种:
$content=str_replace("\n","",$content);
echo $content;
第二种:
$content=preg_replace("/\s/","",$content);
echo $content;
呵呵。
[个人原创]C++学习,在函数中,数组参数退化为指针
Php/Js/Shell/Go jackxiang 2011-8-4 10:16
代码片段:
输出:
From main function:
10
jackxiang
From fun function:
4
jackxiang
此例说明:在函数中,数组参数退化为指针,所以函数fun中的sizeof(a)的内容永远输出为4。
输出:
From main function:
10
jackxiang
From fun function:
4
jackxiang
此例说明:在函数中,数组参数退化为指针,所以函数fun中的sizeof(a)的内容永远输出为4。
平时我们爱使用Curl来实现Http协议的接口调试,包括Post,Get,Etc。
然而,近来发现Suse enterprise sp2的64位机上没有这个Curl的PHP扩展,
于是,想了想,我使用了PHP的方法来实现了对其它接口的访问,包括Cookie头的发送,简单Demo如下:
vi file_get_contents.php
接收简单Demo代码,test3.php:
测试结果:
root@172.25.38.**:/home/jackxiang/php# php file_get_contents.php
得证。EOF
然而,近来发现Suse enterprise sp2的64位机上没有这个Curl的PHP扩展,
于是,想了想,我使用了PHP的方法来实现了对其它接口的访问,包括Cookie头的发送,简单Demo如下:
vi file_get_contents.php
接收简单Demo代码,test3.php:
测试结果:
root@172.25.38.**:/home/jackxiang/php# php file_get_contents.php
得证。EOF
Q:本人长时间咳黄痰,鼻子感觉有些火烧感,请问吃些什么药好呢,如果从中医的角度来看是风寒还是风热引起的呢,怎么在日常中注意保养身体呢,谢谢
A:作为一名 AI 语言模型,我不能对你的身体状况做出诊断或提供具体的医疗建议。如果你一直在咳嗽并且出现了黄痰和鼻子火烧感,请尽快咨询你的医生或就近的医疗机构,以获得专业的建议和治疗。
如果你想从中医角度来看待这个问题,通常情况下,咳嗽黄痰和鼻子火烧感可能与风热或者风寒引起的。风热和风寒都是中医理论中的病邪,会影响身体的正常功能。风热主要表现为咳嗽、喉咙疼痛、鼻塞等症状,而风寒则表现为咳嗽、喉咙痛、流清鼻涕等症状。
如果你想在日常生活中保持身体健康,你可以尝试以下方法:
合理饮食,注意营养均衡,多食用蔬菜、水果等新鲜食品,少食用油腻、辛辣等刺激性食品。
保持良好的生活习惯,如定时作息、适量运动、不熬夜等。
注意保持身体的温暖,避免受凉和受风,尤其是在春秋季节和寒冷的冬天。
避免吸烟和二手烟的影响,保持室内空气的清新。
最后,请记住,如果你感到身体不适,最好及时咨询医生的意见,以便获得更好的治疗和建议。
枇杷止咳糖浆是治疗风寒还是风热感冒的咳嗽?
枇杷止咳糖浆是一种传统中药制剂,其主要成分是枇杷叶、桔梗、杏仁等。它常被用于治疗咳嗽和喉咙疼痛等症状。
根据中医理论,咳嗽分为风寒咳和风热咳两种类型。风寒咳嗽通常伴随着寒冷的症状,如头痛、身体发冷、流鼻涕等,而风热咳嗽则通常伴随着发热、喉咙疼痛、口干等症状。
枇杷止咳糖浆主要用于治疗风热感冒的咳嗽,其功效为清热解毒、化痰止咳。因此,如果你患有风热感冒的咳嗽,可以考虑使用枇杷止咳糖浆进行治疗。但如果你患有风寒咳嗽,枇杷止咳糖浆可能并不适用,需要根据具体症状选用其他的中药制剂进行治疗。建议在服用中药前咨询医生或中医师的建议,以确保选择正确的药物。
复方甘草口服溶液是治疗风寒还是风热感冒的咳嗽?
复方甘草口服溶液可用于治疗风寒和风热引起的咳嗽,但其治疗机理和用法略有不同。
对于风寒感冒引起的咳嗽,复方甘草口服溶液可以用来缓解咳嗽、化痰、止咳等症状。这是因为甘草具有温中止咳、润肺化痰的作用,可舒缓喉咙不适感、促进咳痰,还可以增强机体免疫力,帮助身体抵御感染。
对于风热感冒引起的咳嗽,复方甘草口服溶液也可以用来缓解咳嗽,但其作用机理略有不同。此时,甘草主要发挥的作用是清热解毒、润肺止咳,帮助清除体内热毒,减轻喉咙肿痛和痰液黏稠等症状。
总之,复方甘草口服溶液可以用于治疗风寒和风热引起的咳嗽,但其用法和治疗机理可能略有差异,建议在医生的指导下使用。
板蓝根是治疗风寒还是风热?
板蓝根在中医中被归类为清热解毒的草药,它的功效是清热解毒、凉血止血,可以用于治疗热毒引起的发热、咽喉肿痛、口腔溃疡等症状。因此,板蓝根通常被用于治疗风热引起的症状,而不是治疗风寒。
干咳早期:甘草口服液
咳嗽有痰:一般还是感冒引起的,急支糖浆。(生姜[火姜]+紫苏+分葱[细葱]+红糖)
时间久:急支糖浆饭前+板蓝根饭后。晚上安乃近发汗。
背心:背心凉热敷,不凉就是风热,另外一种治疗方法。
阅读全文
A:作为一名 AI 语言模型,我不能对你的身体状况做出诊断或提供具体的医疗建议。如果你一直在咳嗽并且出现了黄痰和鼻子火烧感,请尽快咨询你的医生或就近的医疗机构,以获得专业的建议和治疗。
如果你想从中医角度来看待这个问题,通常情况下,咳嗽黄痰和鼻子火烧感可能与风热或者风寒引起的。风热和风寒都是中医理论中的病邪,会影响身体的正常功能。风热主要表现为咳嗽、喉咙疼痛、鼻塞等症状,而风寒则表现为咳嗽、喉咙痛、流清鼻涕等症状。
如果你想在日常生活中保持身体健康,你可以尝试以下方法:
合理饮食,注意营养均衡,多食用蔬菜、水果等新鲜食品,少食用油腻、辛辣等刺激性食品。
保持良好的生活习惯,如定时作息、适量运动、不熬夜等。
注意保持身体的温暖,避免受凉和受风,尤其是在春秋季节和寒冷的冬天。
避免吸烟和二手烟的影响,保持室内空气的清新。
最后,请记住,如果你感到身体不适,最好及时咨询医生的意见,以便获得更好的治疗和建议。
枇杷止咳糖浆是治疗风寒还是风热感冒的咳嗽?
枇杷止咳糖浆是一种传统中药制剂,其主要成分是枇杷叶、桔梗、杏仁等。它常被用于治疗咳嗽和喉咙疼痛等症状。
根据中医理论,咳嗽分为风寒咳和风热咳两种类型。风寒咳嗽通常伴随着寒冷的症状,如头痛、身体发冷、流鼻涕等,而风热咳嗽则通常伴随着发热、喉咙疼痛、口干等症状。
枇杷止咳糖浆主要用于治疗风热感冒的咳嗽,其功效为清热解毒、化痰止咳。因此,如果你患有风热感冒的咳嗽,可以考虑使用枇杷止咳糖浆进行治疗。但如果你患有风寒咳嗽,枇杷止咳糖浆可能并不适用,需要根据具体症状选用其他的中药制剂进行治疗。建议在服用中药前咨询医生或中医师的建议,以确保选择正确的药物。
复方甘草口服溶液是治疗风寒还是风热感冒的咳嗽?
复方甘草口服溶液可用于治疗风寒和风热引起的咳嗽,但其治疗机理和用法略有不同。
对于风寒感冒引起的咳嗽,复方甘草口服溶液可以用来缓解咳嗽、化痰、止咳等症状。这是因为甘草具有温中止咳、润肺化痰的作用,可舒缓喉咙不适感、促进咳痰,还可以增强机体免疫力,帮助身体抵御感染。
对于风热感冒引起的咳嗽,复方甘草口服溶液也可以用来缓解咳嗽,但其作用机理略有不同。此时,甘草主要发挥的作用是清热解毒、润肺止咳,帮助清除体内热毒,减轻喉咙肿痛和痰液黏稠等症状。
总之,复方甘草口服溶液可以用于治疗风寒和风热引起的咳嗽,但其用法和治疗机理可能略有差异,建议在医生的指导下使用。
板蓝根是治疗风寒还是风热?
板蓝根在中医中被归类为清热解毒的草药,它的功效是清热解毒、凉血止血,可以用于治疗热毒引起的发热、咽喉肿痛、口腔溃疡等症状。因此,板蓝根通常被用于治疗风热引起的症状,而不是治疗风寒。
干咳早期:甘草口服液
咳嗽有痰:一般还是感冒引起的,急支糖浆。(生姜[火姜]+紫苏+分葱[细葱]+红糖)
时间久:急支糖浆饭前+板蓝根饭后。晚上安乃近发汗。
背心:背心凉热敷,不凉就是风热,另外一种治疗方法。
阅读全文
代码1:
Result:
1X1=1 1X2=2 1X3=3 1X4=4 1X5=5 1X6=6 1X7=7 1X8=8 1X9=9
2X2=4 2X3=6 2X4=8 2X5=10 2X6=12 2X7=14 2X8=16 2X9=18
3X3=9 3X4=12 3X5=15 3X6=18 3X7=21 3X8=24 3X9=27
4X4=16 4X5=20 4X6=24 4X7=28 4X8=32 4X9=36
5X5=25 5X6=30 5X7=35 5X8=40 5X9=45
6X6=36 6X7=42 6X8=48 6X9=54
7X7=49 7X8=56 7X9=63
8X8=64 8X9=72
9X9=81
代码2:
Result2:
1X1=1
1X2=2 2X2=4
1X3=3 2X3=6 3X3=9
1X4=4 2X4=8 3X4=12 4X4=16
1X5=5 2X5=10 3X5=15 4X5=20 5X5=25
1X6=6 2X6=12 3X6=18 4X6=24 5X6=30 6X6=36
1X7=7 2X7=14 3X7=21 4X7=28 5X7=35 6X7=42 7X7=49
1X8=8 2X8=16 3X8=24 4X8=32 5X8=40 6X8=48 7X8=56 8X8=64
1X9=9 2X9=18 3X9=27 4X9=36 5X9=45 6X9=54 7X9=63 8X9=72 9X9=81
Result:
1X1=1 1X2=2 1X3=3 1X4=4 1X5=5 1X6=6 1X7=7 1X8=8 1X9=9
2X2=4 2X3=6 2X4=8 2X5=10 2X6=12 2X7=14 2X8=16 2X9=18
3X3=9 3X4=12 3X5=15 3X6=18 3X7=21 3X8=24 3X9=27
4X4=16 4X5=20 4X6=24 4X7=28 4X8=32 4X9=36
5X5=25 5X6=30 5X7=35 5X8=40 5X9=45
6X6=36 6X7=42 6X8=48 6X9=54
7X7=49 7X8=56 7X9=63
8X8=64 8X9=72
9X9=81
代码2:
Result2:
1X1=1
1X2=2 2X2=4
1X3=3 2X3=6 3X3=9
1X4=4 2X4=8 3X4=12 4X4=16
1X5=5 2X5=10 3X5=15 4X5=20 5X5=25
1X6=6 2X6=12 3X6=18 4X6=24 5X6=30 6X6=36
1X7=7 2X7=14 3X7=21 4X7=28 5X7=35 6X7=42 7X7=49
1X8=8 2X8=16 3X8=24 4X8=32 5X8=40 6X8=48 7X8=56 8X8=64
1X9=9 2X9=18 3X9=27 4X9=36 5X9=45 6X9=54 7X9=63 8X9=72 9X9=81
在开发中,我们碰到的跨域主要还是纠结在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