Month: 十二月 2009

扩展XHProf的存储方式

关于XHProf的安装,不多讲,可以参见这篇博客 http://www.ooso.net/archives/522

最近在公司的App Engine平台上添加了XHProf功能,在整合过程中,我们把调试数据存放到了用户自己的存储空间中,这样更便于管理.

其实XHProf为存储方式的定制留了非常方便的接口.不过我们还是先从XHProf的流程说起.

XHProf的工作流程

XHProf其实是由两部分组成的.一个php模块,一个php项目.

php模块负责的内容是把当前脚本在运行中产生的调试信息dump成一个php数组;

而php项目则负责返回的数据的存储和展现.

php模块可以通过pecl自动进行安装,不过两周前我们安装的时候,似乎因为.configure文件目录路径不对.如果你pecl安装不成功.可以直接下载源代码编译.

这个模块通过两个函数来打开和关闭调试信息,xhprof_enable()和xhprof_disable(); 其中 xhprof_disable() 会将调试信息以多维数组的形式返回.

接下来就是保存信息了.默认的方式是new一个 XHProfRuns_Default对象,调用其save_run方法.

该方法会将这个数组存放到你在php.ini中XHProf段配置的xhprof.output_dir下.并返回给你一个run_id.

拿着这个run_id,再通过XHProf包中提供的php展示程序(xhprof_html目录下的部分),就能顺利的取得调试信息并按table或者图表显示了.

扩展XHProfRuns

查看XHProf_runs的实现,我们发现其实只要写一个class实现iXHProfRuns接口,我们就可以非常方便的实现自己的存储.而iXHProfRuns只有两个方法,分别是get_run和save_run.

之后,将index和callgraph页面中的new XHProfRuns_Default换成 new XHProfRuns_Mysql即可.…

选框架记

去年创业的时候,在选择框架这件事情上,我们折腾了很久.

为了遵循”不要重复的发明轮子”的伟大号召,我们决定选一个开源框架.

于是在对CakePHP,CodeIgniter和ZendFramework等框架进行了一番比较之后,我们觉得CI看起来更舒服一些.于是CI就成为了我们的主框架.

在用CI写完了一个历时一年的项目后,我们一致同意换掉CI.

不是这些框架不强大.不是这些框架不优秀,恰恰相反.

它们太强大了,强大到80%的功能我们都不会用到;它们太优秀了,优秀到我们team的一些菜鸟程序员完全理解不了.

写框架的人把框架当成是个人技术的展览馆,为了玩出华丽的技巧穷其心思;

用框架的人把框架看成是武林秘籍,希望能一朝练成绝技,而后一劳永逸.

其实我们用框架,不过是为了快点把公司那点事情做完,然后回家睡自己的大头觉么…

当我们意识到这一点后,我们决定自己开发一个框架.

这个框架要足够的简单,只做必须做的事情.框架的接口也要足够的易学,无须了解高深的面向对象.

就这样LazyPHP被写了出来.它只有一个简单的MVC结构,layout部分已经算是这个框架最复杂的部分;它的主要接口都是面向过程的,只有20多个公用函数.

我并不是在这里推销LazyPHP,我想说的是.

框架是拿来用的,不是拿来看的.以最低的成本,完成最多的事情的框架才是好框架.

这是我们花了一年时间才明白的道理.无论是用开源的,还是自己开发,你真的应该用一个能让你雇的最菜的程序员也能5分钟学会的框架.…

PHP文档工具,PHPDocumentor续

关于PHPDocumentor,我在05年的PHP&More杂志第二期中介绍过其基本用法.没想到给它写续篇时,已经是四年之后.

这么多年过去了,PHPDocumentor依然是PHP文档工具里的不二选择,虽然版本进化不大,不过更新却一直在进行.

去年8月,PHP4已经退出历史舞台,很多标记,如@abstract,@public已经可以直接从代码中获取,需要手工声明的地方也越来越少了.

本篇重点补充之前文章没有详细讲的几个细节问题:

  • 如何区分文件和class的DocBlock
  • 如何将演示代码写入注释
  • 如何生成中文文档
  • 如何编译CHM文件

如何区分文件和class的DocBlock

PHPDocumentor生成的文档通常通过两个维度进行索引,一个是文件列表,一个class tree.

文件列表的注释内容依赖于File DocBlock;而Class的注释内容则依赖于Class DocBlock.

如果一个文件里边只有一个class,那么写在class之前的DocBlock就会让PHPDoc犯晕,这个Doc到底是File的还是Class的呢?

所以,为了避免PHPDoc抛出warning,我们最好在文档最上边和Class最前边分别加上DocBlock.这样就OK了.

另外需要注意,只有包含了@package的注释块才会被认为是文件级别或者Class级别的DocBlock.

如何将演示代码写入注释

我们在使用别人的代码的时候,最需要的就是示范代码,不用细细的去看清每一个函数的用法,只要照猫画虎就能用.

同样的,在我们写代码的时候,最好也把这些快速上手的演示代码写到文档里边.

PHPDocumentor提供了两种方式整合示范代码.一种是@example标记;一种是code标签.

@example标记

在注释块中,写上@example 标记,后边跟上演示代码的文件路径,PHPDocumentor会自己为对应的代码生成一个页面,并进行语法高亮.


/*
* @example ../example/code/mysql.class.php
*/

Code标签

Code标签则需要直接写到注释块中间,我更趋向于Code标签,因为这种方式下,代码和注释是一体的,都在同一个文件里边,当代码产生变动时,注释更容易得到更新.

/*
* <code>

* phpinfo();

* </code>

* @author Easy

*/

特别需要注意的是,Code标签需要写到各种@标记之前,否则将不会生效.

如何生成中文文档

虽然大家的英文可能非常好,但是出于团队协作的便利,在书写文档时,我还是建议大家尽可能采用中文.

PHPDocumentor在生成中文页面时,会产生乱码问题.这主要是因为它的模板里边默认的字符集是ISO-8859-1的.只需要修改对应的字符集为GBK或者UTF-8,就能在生成的文档中正确显示中文了.

PHPDocumentor采用Smarty作为模板,所有的模板都放置在PHPDocumentor/Converters/下,修改对应的文件即可.如采用的是默认的html模板,其模板文件在

phpDocumentor/Converters/HTMLframes/templates/default/templates

下,修改其中的head.tpl、index.tpl、blank.tpl、top_frame.tpl文件的charset为GBK/UTF-8即可.

如何编译CHM文件

要编译生成CHM文件,首先需要在PHPDocumentor的Output中,选择CHM的模板.这样PHPDocumentor按照CHM文件的规范为我们组织文件.在输出的目录根下有一个phpdoc.hhp文件

然后我们需要HTML Help Workshop(点这里下载).CHM的编译非常简单,将phpdoc.hhp拖拽到解压后的hhc.exe文件上即可.

另外,PHPDocumentor生成的目录是同时包含文件列表和Class列表的,读起来反而让人觉得重复,一般我会去掉其中的文件列表部分.要想在CHM中去掉这一部分,在输出目录的根下有一个content.hhp文件,包含了目录的各级列表,采用的是UL和LI标签来表达的,把你不需要的部分删除,重新编译就可以得到一份清晰易读的CHM文件了.…

好吧,我又搬家了

我已经不记得这是第多少次换blog地址了.自从我大学开始写blog以来我就陆陆续续的换程序,换空间,换域名.

本来在上一次我把自己的blog放到SAE上时,就发誓不再到处乱搬了.

不过在CNNIC宣布个人无权使用CN域名后,我的强迫症又犯了.

你说万一哪天我那个CN域名被强制收回了,我这个一天还有十多个IP访问的博客岂不是被强制拆迁了.

不行,士可杀不可辱,与其被人强制拆迁,不如我先自己搬出拆那吧.

于是嘛,就有了这个blog了.原来的博客文章不多,就不再转移了.…