手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表分类:PHP

杂谈

1、高春辉表示升级到了5.3.3,不知道是不是手机之家,但,我真的不敢升级,即使我的版本中basename对中文的处理一塌糊涂,我也不敢升,因为实在不知道升级后会出现什么样奇怪的错误。高春辉说:

http://www.paulgao.com.cn/index.php?itemid=150
  1. 1、parse_url 执行出错的时候不再报 warning 错误了,不再需要使用 @ 了,但是要仔细判断结果是否为 FALSE 了;  
  2. 2、FPM 终于内置了,配置文件从 XML 改成 INI 方式了,增加了例如 xxx.com/status 的报告,和例如 xxx.com/ping 的健康检查功能了,挺好;  
  3. 3、另外这次编译的时候把 ereg 模块也干掉了。以前是为了兼容 PMA,现在 PMA 也不用 ereg 了,就可以 DROP 它了。  

2、对于typecho,我对牧师的网站上的两个模版,我很喜欢。。。

  1. http://typecho.demo.m4go.com/m4tom/ 
  2. http://bl.typecho.me/ 

这可能是个人爱好问题,并非其他模版不好看。

3、上次我在博客里贴了老王的:<?php if($a = 100 && $b= 200){var_dump($a,$b);}?>,结果风雪之隅解释的更详细:http://www.laruence.com/2010/07/26/1668.html,他说,手册上说了:

XML/HTML代码
  1. Note: Although = has a lower precedence than most other operators, PHP will still allow expressions similar to the following: if (!$a = foo()), in which case the return value of foo() is put into $a.   
差不多就是说:其实也简单, 运算符优先级是在存在二义性文法的时候的一种规约规则选择的手段, 而PHP的语法分析文件定义中, 却让等号和T_BOOLEAN_AND(&&)之前不存在了规约冲突.

Tags: 高春辉, typecho, 运算符, 风雪之隅

pack 和 unpack 的使用

来自kakapo的博客:http://www.kakapo.cn/blog/read.php?112,主要是实在不懂。事实上,我看完,我也不懂。

      任何一款拥有socket操作能力的语言都有一个专门用于组包的函数,php也不例外!          

      用了很久php了却很少有机会用php进行一些二进制操作。 最近用php写一个socket客户端连接一个用C++语言开发的游戏服务端。 服务器端开发人员使用了二进制的形式来定义协议的格式。协议格式如下:

   包头(2bytes)+加密(1byte)+命令码(2bytes)+帧内容

1.包头的内容是记录帧内容的长度;
2. 加密:0表示不加密,1表示加密;
3. 命令码为服务端命令识别符号;

    一开始不了解php原来有pack可以来组装二进制包, 走了弯路,让服务端开发人员用C语言帮忙开发了的几个内存操作函数,按照协议规则返回二进制包,然后我将这几个方法编译成一组扩展函数供php使用。
   
    话归正题,本文是介绍如何使用pack和unpack这两个方法的。php官方手册举例太少,不能很容易理解,特别是那些格式化参数的使用。

转 摘的参数中文说明:

pack/unpack 的摸板字符字符 含义
a 一个填充空的字节串
A 一个填充空格的字节串
b 一个位串,在每个字节里位的顺序都是升序
B 一个位串,在每个字节里位的顺序都是降序
c 一个有符号 char(8位整数)值
C 一个无符号 char(8位整数)值;关于 Unicode 参阅 U
d 本机格式的双精度浮点数
f 本机格式的单精度浮点数
h 一个十六进制串,低四位在前
H 一个十六进制串,高四位在前
i 一个有符号整数值,本机格式
I 一个无符号整数值,本机格式
l 一个有符号长整形,总是 32 位
L 一个无符号长整形,总是 32 位
n 一个 16位短整形,“网络”字节序(大头在前)
N 一个 32 位短整形,“网络”字节序(大头在前)
p 一个指向空结尾的字串的指针
P 一个指向定长字串的指针
q 一个有符号四倍(64位整数)值
Q 一个无符号四倍(64位整数)值
s 一个有符号短整数值,总是 16 位
S 一个无符号短整数值,总是 16 位,字节序跟机器芯片有关
u 一个无编码的字串
U 一个 Unicode 字符数字
v 一个“VAX”字节序(小头在前)的 16 位短整数
V 一个“VAX”字节序(小头在前)的 32 位短整数
w 一个 BER 压缩的整数
x 一个空字节(向前忽略一个字节)
X 备份一个字节
Z 一个空结束的(和空填充的)字节串
@ 用空字节填充绝对位置


string pack ( string $format [, mixed $args [, mixed $...]] )

一些规则:
1. 每个字母后面都可以跟着一个数字,表示 count(计数),如果 count 是一个 * 表示剩下的所有东西。
2.如果你提供的参数比 $format 要求的少,pack 假设缺的都是空值。如果你提供的参数比 $format 要求的多,那么多余的参数被忽略。

下面还 是用例子来说明用法会容易理解一点:

关于Pack:

下 面的第一部分把数字值包装成字节:
$out = pack("CCCC", 65, 66, 67, 68);      # $out 等于"ABCD"
$out = pack("C4", 65, 66, 67, 68);         # 一样的东西

下面 的对 Unicode 的循环字母做同样的事情:
  $foo = pack("U4", 0x24b6, 0x24b7, 0x24b8, 0x24b9);

下面的做类似的事情,增加了一些空:
  $out = pack("CCxxCC", 65, 66, 67, 68);      # $out 等于 "AB\0\0CD"

打包你的短整数并不意味着你就可移植了:
  $out = pack("s2", 1, 2);        
# 在小头在前的机器上是 "\1\0\2\0"
# 在大头在前的机器上是 "\0\1\0\2"

在二进制和十六进制包装上,count 指的是位或者半字节的数量,而不是生成的字节数量:
  $out = pack("B32", "...");
    $out = pack("H8", "5065726c");         # 都生成“Perl”

a 域里的长度只应用于一个字串:
  $out = pack("a4", "abcd", "x", "y", "z");      # "abcd"

要绕开这个限制,使用多倍声明:
  $out = pack("aaaa",    "abcd", "x", "y", "z");   # "axyz"
   $out = pack("a" x 4,   "abcd", "x", "y", "z");   # "axyz"

a 格式做空填充:
  $out = pack("a14", "abcdefg");         # " abcdefg\0\0\0\0\0\0"


关于unpack:

array unpack ( string $format, string $data )

$data = "010000020007";
unpack("Sint1/Cchar1/Sint2/Cchar2",$data);

## array('int1'=>1, 'char1'=>'0','int2'=>2,'char2'=>7);

      最后本文开头讲到的协议使用pack/unpack 举例程序代码为 :

PHP代码
  1. $lastact   = pack('SCSa32a32',0x0040, 0x00, 0x0006, $username$passwd );  
  2.   
  3. unpack('Sint1/Cchar1/Sint2/Cchar2/',$lastmessage);  

Tags: pack, unpack

IE中iframe跨域丢失Session问题(续 p3p)

P3P,不算是新名词,但还是有些人不清楚。事实上我也不清楚。。。在百度上看到有这玩意就备份下来。说真的,我只是知道用,但不知道为什么用。额。。很明显,因为在ucenter同步的时候,在discuz的ui/api里有写过。

看内容吧。。。。

IE6/IE7支持的P3P(Platform for Privacy Preferences Project (P3P) specification)协议默认阻止第三方无隐私安全声明的cookie,Firefox目前还不支持P3P安全特性,firefox中自然也不存 在此问题了。

在frameset里面,也就是里面的frame是来自第三方站点(不同IP或不同域名),那么默认情况下IE会自动禁用这些站点的cookie, 也就是在请求某url时在HTTP header里不发送它们的cookie,包括session的cookie。注意,这些站点在response里面设置的cookie还是会被发送到浏 览器的。

在用户浏览a.php时 A.com写入的为第一方Cookie,其嵌入的iframe指向 b.php.这时B.com写入的就为第三方Cookie了,所以它是被IE当在了大门外。 所以,每次当用户提交的cookie提交时,就挂掉了.因为传不到真实的服务器.

解决方案.

PHP程序,可以直接在B网站中写入www.kobsky.cn 小眼世界ýñ ëÕRÏz-Z

PHP代码
  1. <?php  
  2. header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');  
  3. ?>  
这样就能接受第三方的Cookie啦。

 

lighttpd的服务器

XML/HTML代码
  1. server.modules    = ("mod_setenv")  
  2. setenv.add-response-header = ( "P3P" => "CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'")  
apache的服务器

XML/HTML代码
  1. <VirtualHost>  
  2. Header set P3P 'CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'  
  3. </VirtualHost>  
IIS的服务器www.kobsky.cn 小眼世界ýñ ëÕRÏz-Z

增加一个网站http头来解决问题;www.kobsky.cn 小眼世界ýñ ëÕRÏz-Z
管理工具——〉选择一个网站——〉属性——〉 http头,增加一个http头www.kobsky.cn 小眼世界ýñ ëÕRÏz-Z
然后输入头名:P3Pwww.kobsky.cn 小眼世界ýñ ëÕRÏz-Z
输入头内容:CP=CAO PSA OUR

jsp页面:

XML/HTML代码
  1. <%  
  2. response.setHeader("P3P","CP=CAO PSA OUR");  
  3. %>  
java代码最简单的办法,增加一个filte:
Java代码
  1. public class TransNameFilter extends HttpServlet implements Filter {  
  2. private static org.apache.commons.logging.Log logWriter =  
  3.    LogFactory.getLog(TransNameFilter.class.getName());  
  4.   
  5. /** 
  6. * 
  7. */  
  8. public TransNameFilter() {  
  9.    super();  
  10.   
  11. }  
  12. /* (非 Javadoc) 
  13.    * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) 
  14.    */  
  15. public void init(FilterConfig arg0) throws ServletException {  
  16.   
  17. }  
  18.   
  19. /* (非 Javadoc) 
  20. * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) 
  21. */  
  22. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  
  23.    throws IOException, ServletException {  
  24.   
  25.    HttpServletRequest hreq = (HttpServletRequest) request;  
  26.    String transName = hreq.getParameter("transName");  
  27.    if (Util.isNullOrEmpty(transName)) {  
  28.     logWriter.fatal(" there is no transName for this request");  
  29.    } else {  
  30.   
  31.     logWriter.info(" transName is " + transName);  
  32.    }  
  33.     
  34.    HttpServletResponse res = (HttpServletResponse) response;  
  35.         //iframe引起的内部cookie丢失  
  36.    res.setHeader("P3P","CP=CAO PSA OUR");  
  37.    if (chain != null)  
  38.     chain.doFilter(request, response);  
  39.   
  40. }  
  41.   
  42. /* (非 Javadoc) 
  43.    * @see javax.servlet.Filter#destroy() 
  44.    */  
  45. public void destroy() {  
  46.   
  47. }  
  48.   
  49. }  

Tags: session, cookie, p3p

PHP笔记

1、老王的乱炖中写了一个例子。

写代码要细心【http://hi.baidu.com/thinkinginlamp/blog/item/5e8062d9b33ccc2110df9b2a.html】

看一段PHP代码,设想一下它的输出结果,可以用来做面试题:

<?php if ($a = 100 && $b = 200) { var_dump($a, $b); } ?>

我眼睛一闭就随便想了一下$a=100,$b=200。然后看标题是写代码要细心。再仔细看看。才发现。。。额,我错了。

2、yaml

yaml这东西有据可证以来,好象在国内,应该算是QeePHP最早拿来做应用(我是指开源项目中),确实这东西挺方便【现在新浪sae的配置文件就是用yaml的】

初学者可以看看http://www.lanyg.com/blog/?p=63,Tim在这里写了一些简单的入门。不过我相信,足够你使用了。

yaml主要还是写起来方便。而且不用过多的担心语法(xml还需要闭合。array的话也需要注意PHP语法),yaml反正解析出来,要么不对,要么就正确。至少不会报一些奇怪的错误。

3、HTTP协议。

这篇也是来自于tim的博客:http://www.lanyg.com/blog/?p=33,他也是转载的csdn的文章http://blog.csdn.net/gueter/archive/2007/03/08/1524447.aspx,原作者是jeffrey,内容挺长。不过如果你想要模拟http POST和GET数据,你真的可以看一下这一篇东西

它介绍了【HTTP协议详解之消息报头】,也教你如何用telnet查看http协议的通讯过程(当然现在我们都是用firebug或者fildder之类的工具),文章最后介绍了一些补充协议,如代理(proxy),通道(tunnel)等。值得一看。

Tags: yaml, operation

typecho 插件开发(三)

在typecho开发插件的时候,很有可能会用到关联插件(即,部分信息需要从其他插件里来读取)因此,在插件激活的时候就得先判断是否关联插件已经启用。

最初我的代码是:

PHP代码
  1. $mailOptions = Typecho_Widget::widget('Widget_Options')->plugin('CommentToMail');  
  2. if(emptyempty($mailOptions)){//这里会出现两个empty,这是编辑器的关系,代码中只有一个  
  3.     throw new Typecho_Plugin_Exception(_t('对不起,数据库备份插件需启用CommentToMail插件。'));  
  4. }  
但是在这样处理的时候,会提示“找不到CommentToMail插件的配置信息”,直接就抛出异常

于是代码改成:

PHP代码
  1. try{  
  2.     $mailOptions = Typecho_Widget::widget('Widget_Options')->plugin('CommentToMail');  
  3. }catch(Exception $e){  
  4.     throw new Typecho_Plugin_Exception(_t('对不起,数据库备份插件需启用CommentToMail插件。'));  
  5. }  

于是这样的出错提示信息就较为友好了。

由于关联了其他插件,因此在处理的时候,还要再判断这个$mailOption是否存在,因此我把它设为了protected static $mailOptions,然后在要处理的页面会判断这个变量是否为empty。如果是后台处理就抛出异常,前台处理则直接return;不作继续

Tags: typecho, 插件, 技巧