出处:http://www.oschina.net/question/57579_50368 http://www.oschina.net/question/1579_49262 。 引子 半夜闹肚子,如厕期间思来想去,针对昨天下午决定删博删号的事情,前前后后的想了一遍。 掀开电脑,打开osc,看到红薯已然开始在更新osc的各种新闻
出处:http://www.oschina.net/question/57579_50368
http://www.oschina.net/question/1579_49262。
引子
半夜闹肚子,如厕期间思来想去,针对昨天下午决定删博删号的事情,前前后后的想了一遍。
掀开电脑,打开osc,看到红薯已然开始在更新osc的各种新闻,包括这次事件的一些善后处理,整个过程中,红薯没有对我进行任何留言,也没有给我发过任何邮件,可见他的立场。对于我决定删号的事情,我认为我做对了。整个事件的始末,在于这篇《五大受损 全面解析php的糟糕设计》,在鄙人的看法看来,这是一篇十分不专业的文章,我相信包括宏哥还有其它不认同该文章的部分用户,也会有同样的心情。文章传达出一些信息,很遗憾,居然连红薯这样的水平的人,也没有看出来,当然,因为他没用过php开发实际项目,他不明白,也很理所当然。首先这些信息包括了:
1、文章中说的问题,缺乏客观性和论据。
2、他抱怨php的一些特性,根本没有好好的去看官方文档。
3、作者本身就是一个神经质,这可以从开篇的第一句可以得知:“我的脾气古怪. 我会抱怨很多东西. 这个星球上大多数技术我都不喜欢.”。呼应文章结尾的:“如果你仅了解php而对学习其它东西感兴趣, 可以看看 python 教程”,显然比较php和python,作者更推崇python。而以开篇的这第一句“这个星球上大多数技术我都不喜欢”,所以,其实python他也不喜欢,迟早有一天,他也会以同样的态度来喷python。
尽信书不如无书,可是无限的质疑,从根本上说,就是这个人什么都不是,什么都不精通,什么都只知道个皮毛,然后就在喷,对于这样一种人提出的观点,围观者最好戴上理性的眼镜,不然自己被带入了歧途,可不能赖发这些文章的人别有用心。
而撰写本文的出发点,就是为了避免造成这种误入歧途的效果。一个额外的用意,是强烈指责红薯和osc的不专业性。
php的模式——务实
最早php的产生,目的就是为了能够快速的修改网页的内容,而设计的php——事实上以php的实现水平,较之ruby、python,真的显得蹩脚和缺乏远见,和长期规划。
正是缺乏大局观,php发展渐渐失去方向,丧失市场,而后zend这个商业团队入主php核心,为php加入了zend engine,使用zend api重新改造了php核心部分,使其具备更加长远的发展前景,增加了可扩展性,同时也解决了当时php被诟病的一些问题。 事实上,php比起这个世界上的任何一个开发语言来说,都显得要尴尬。这种尴尬的表面现象是,php之父并不具有十分深邃、专业的计算机理论基础,而php这个语言几乎无法体现任何“进步”、“前卫”的编程哲学。而同时,作为一个开源的项目,其核心部分的zend engine又是由一个商业机构支撑起来的。
比之于各种流行语言,c、c++、c#、java、scala,这些语言首先具有学院派的理论研究为基础支撑,而如python、ruby、javascript等,又都集成了各种先进的编程特性和独特的编程哲学。php矗立之于他们面前,真有如一个先天残疾的侏儒,抬不起头来。
从最早的c风格的函数,这是每个php程序员每天都必须打交道的,每天工作都必须要使用的函数。到朝c++风格转换的,一批静态类,以及php 4到php 5过渡时期那不伦不类的class模型。以及之后的仿java风格的,大量的可实例化的class,spl标准接口类,等等。
我接触php也是php 5之后的事情了,所以我并不了解那之前发生了什么,对于我来说,无论是什么风格,都只是一个api而已。但我想着重谈谈的是,php 5.3,5.4两个版本特性变更。
php 5.3的一大特点是namespace和闭包的支持,在pear规范中,php的命名空间,使用_进行区隔(也包括zend framework 1的包规范),比如,zend_http_core,所映射的物理路径为:zend/http/core.php,而core.php中的classname应为:class zend_http_core。
一个最大的问题在于,这样的类名过长,这会引发很多问题,这里就不一一累述了。其次,这种命名机制无法解决对项目迅速重构的需要,比如一个既有的项目,已经封装了一个string的class,也许基于客户需求,需要彻底重构这个class,可是大量的既有代码大量存在new string的问题。而你几乎没有任何切入点可以去rewrite一个classname的指向,比如我重构了string类,改为jan_string,那么所有的代码,需要大量的搜索和替换掉原有的string关键字。
而php 5.3的namespace机制,通过最低最低的性能损耗,提供给你一个class rewrite的解决方案,新重构的string类,使用namespace,jan\string,而在所有使用了string的文件中,声明一句:use jan\string as string,则所有问题都迎刃而解。
同时,该namespace机制是支持autoload的api的,你即使未require或include任何文件,如果你实现了autoload的接口,当你调用use jan\string时,则自动回调用autoload去加载相关的libaray。如果,你的autoload封装不支持这种机制,你也只需要稍微修改你实现的autoload接口,则所有的问题都将迎刃而解。
同时,php团队选择namespace的区隔符,真的是煞费苦心,因为早在php 5.2.x时期,他们就已经尝试引入namespace机制,当时的实现是类java package的机制,而最终放弃该方案。因为namespace所关联的一个核心问题,就是如何从文件系统中迅速关联到相关的文件,而.关键字,对于实现来说,比如jan.string这样一个fullname,仍需要做replace操作。而使用\,无论在windows还是unix系统,你都无须将其进行转换,即可拿来直接使用。这里完全可见php团队对namespace方案的弹尽思虑。
事实上,php的另外一个函数,也是费尽心思巧思量,即realpath函数,这个函数可以将任意路径名转为当前系统规范的路径名,比如/srv/www/abc.php,在windows服务器,他自然会帮你转为\\srv\\www\\abc.php。到了php 5.3之后,该函数不单转换路径名,同时可判断该路径名是否存在(bsd系统不支持,linux和windows我都实际测试过)。5.3以后,该函数的查询结果将被缓存(is_file和file_exists同样),同时增加了两个底层函数,可用于查询相关的缓存结果。
php 5.4,我认为最大的特性更新在于引入了trait和内建web server。前面说了,在选择class的实例化模式时,php选择的是java模式,单继承模式,在声明了大量的类以后,存在一个普遍的问题就是:无法更加灵活的扩充一个已经继承自某个父类的class。关于php的mixin实现,各种稀奇古怪的模式都有,有用__call接口实现的,有用动态加载文件实现,不一而足。
而这个trait,对我倒不陌生,scala里面,早就有所使用。trait的做法,看起来更像是javascript里面的混入机制(将一个object混入另一个object),只是他没有额外声明一个class,并且他的设计目标就是用于混入使用。
通过说明php 5.3和5.4的更新的一些小细节,我的目的旨在说明一点,即php的团队是一个十分务实的团队,从他的更新特性选择就可以看到。事实上我曾在某个时间段里面十分关注php 5.4的todo list,里面描述了很多新特性(用户提议的),包括trait,built in server,还有自动装箱,等等。而他们挑选实现的特性,往往是,实际编程需要,小小的改变,但能够让开发者迅速的扩展可编程范围,提升开发便捷性的更新。
这里还包含另外一个特点,即对php性能的充分重视。php5.2到5.3的更新,5.3到5.4的更新,都重复在提到的一个更新内容是,进一步提升性能、并解决上一个版本影响性能的某个关键性问题。这一点,也充分说明php团队的务实性。
针对原文作者中所抱怨的,php语言更新所带来的问题,我真觉得好笑。静态语言且不论,下面会有专篇来说,针对几个常见的脚本语言而言,ruby、python的升级,可也没有顾忌以前的老版本如何,python自不打说了,选择对的版本,是学好python的第一步,不然你将会为你施展你的python才能而感到一筹莫展。ruby on rails曾在一段时间内,长期不支持ruby 1.9,现在如何我是不得而知。而javascript,由于开发者广泛使用某个基础版本,导致目前浏览器内的实现版本,始终是那个版本。别和我说什么浏览器支持什么新规范,和你的客户说去。
而同比之下,php就是那么简单的,不断发布新版本,不断的尝试将各种便利、实用、性能带给老用户,而不无需做太多的改变,前提是你真的在用php模式开发。
说到php模式,其实有些模棱两可,什么是php模式,没有,真的没有。但它又确实存在,即实用主义,拿来主义,甭提什么面向对象还是面向爹娘。但这个前提是,你真的领悟到php在做的是什么,以及他为什么要这么做。
不统一的命名风格
这是多数人诟病php会提到的一个问题。
比如,我们和java的那些条条框框的命名规范比,那php的命名风格真的是恶心到家了。不过这只是问题的表象,请问,你了解jdk编译器实际上将你的java代码转换成什么了吗?你不知道,你只是拿着jdk提供给你的条条框框给固定化了,使你的思维就认为一切都该如此。而且这种模式还在不断的强化,尤其是那几个java下面很出名的什么什么框架(我真的是连他们的名字都懒得去记),然后巴巴的说自己会这个那个,结果什么都不是。没了框架,没了java,就是个屁。
或者我们和c#比比,c#是一个做派很“open”的语言,注意,这个open是别有所指,指是他对各种新鲜事物和特性的吸收能力。java火了,就丢了vb和asp,来个c#和.net。ruby和python火了,就大造各种脚本引擎(那个什么iron什么的,现在都不知道哪去了),还要把脚本特性引入c#。flash和actionscript火了,就自己搞一套sliverlight。scala出来了,他也来个什么f什么叉的玩意,然后又把泛型引入到c#中。不过他搞这么些玩意,他底层做了些什么,可从来不会告诉你(可能c#现在公开了底层吧,具体我不关心,也不想知道)。
嗯,看着上述说c#这段,觉得内心爽的同学,不得不告诉你一个事实是,我给你下了个套,其实微软要这么做,存在其客观需求,而不是贪新鲜造出来玩得,只是说了你们也不懂,我也不多说了。
相比之下,php的zend engine,是规范的,是可知的,而且是可扩展的。比如众多opcode的缓存扩展,比如xcache、apc,还有zend公司自己的商业化扩展等。我们下载的每份php源代码里面,都有zend engine实现的源代码。而国内,如雪候鸟、胖胖等,都对zend api和zend engine、php core,做过详细的文章介绍,雪候鸟甚至是详细的列明zend engine的编译指令。
骂php的人,请问你凭什么骂?对比java对比c#,php完全走的是标准开源的路线。你拿着c#、java给你的那点玩意,跑来垫吧垫吧的在这里说这说那,请问你对java和c#本身底层的东西又了解多少?或者有本事的,你用c自己写一套?
题外话:国内有个叫做快手的语言,暴露windows的api,提供给开发者迅速开发一些windows工具使用。我很实际的去了解过这个语言,也实际的做过一些小玩意,我真心觉得这套东西挺不错的,起码比起windows sdk要有趣的多。我真的对那些叫骂快手的人感到很奇怪,你们这么厉害,怎么没看你们做点什么,能封装、暴露windows api出来,却有资格在这里说别人做的东西是垃圾?
埋怨php的开发者,我也请问,你们有多认真的去看过php底层实现的代码,有多少人实际去测试和使用过php重大版本升级中所更新的特性?所谓php模式,根本不存在,需要的就是你多看看php的文档,多关注关注php的wiki。
关于风格不统一的问题,还有另外一番说法,请问现在实际开发php的人,有多少人是用记事本来写代码的?没有吧?就算是notapad++、editplus、ultraedit、vim等,这种编辑器,都能智能提示90%的php关键字和常用函数,尤其是vim、ultraedit(editplus我用得不多,所以不了解),你完全可以去定制你所需要的关键字和函数。我相信,多数php的新手,一定会选择使用ide,比如php storm、netbeans、eclipse的pdt、zend studio、phpdesigner、php editor等等,这些能叫得出名字的ide,几乎是与php的版本同步更新的。有了智能提示,比起scala、c、c++,我真的不明白作为一个php开发者,还有什么好抱怨的。
还有,php的文档归档,官方一直都是和php版本更新紧密结合的,php的chm几乎是凡有新版本,每期都更新。而就java的文档库,和msdn而言,php文档实用性可远胜于他们。php的文档,详细列明函数用途,参数作用,哪个参数是引用类型,这个函数在使用时需要额外注意什么情况,每个版本增加了什么新特性,使用时的一个简单的例子(有些重要的函数和class,都会有不止一个的使用示范),还有随着php 5.3的更新,class的说明更加详细。
请不要以什么java、c#的条条框框来看php,他们不会告诉你他们是怎么做的,他们只能给你套上一个又一个的条条框框。也不要以ruby、python的眼光来看待php,他们是跳脱的、前卫的,他们自己仍有诸多问题有待解决而又无法解决。
php就是php。
“吹毛求疵”
>> php 为保持前进不惜代价. 什么都有比没有好.
这个我在前文的叙述中已经说了,我也不想再说明什么了,如果还是觉得,这的确是个问题的,我会说,那你别用php了。
>> 这不是个正确的设计原则. 早期的php受perl影响; 大量的标准库参考c使用 out 参数; oo部分的设计像c++和java.
这个一方面是历史发展的问题,为保证前后兼容所致。同时,java也不过就是你看起来的规范,你也并不了解他实际做了什么了(编译器的实现可没有这么理想化)。而一个最最重要的问题是,务实。比如fopen,他实际上要做的事情已经做完了,为什么要为了看起来舒服点,而要把他删除了,或者改个名字呢?除非你闲的蛋疼没事干。
>> php从其它语言中引入大量的灵感, 但对那些熟知其它语言的人, 仍然难以理解. (int)看起来像 c, 但是 int 并不存在. 命名空间使用 \. 新的数组语法使用 [key => value], 不同于任何其它语言定义hash字面量的形式.
这个也不说了,刚才已经说了一些,而类型的问题,后面会提到。
>> 弱类型(例如, 默默的自动在 strings/mumbers/等间转换)是如此的复杂.
类型匹配的问题,恐怕不只php有,java那蛋疼的==也存在问题。
>> 少量的新特性以新语法实现; 大多数工作通过函数或者看起来像函数的东西完成. 除了类的支持, 这理所当然的需要新的操作符和关键字.
我想请问,哪个语言的更新不是这样呢?如果你这么挑剔,我想说,你别做程序员了,你去玩你自己的手指吧。
>> 本页列出的问题都有官方解决方案 -- 如果你想资助 zend 修复它们的开源编程语言的话.
到目前为止,我觉得zend对于区分商业化和开源两个领域是做得很清晰的,最低限度是,你看得到zend engine的代码,且有大量的产品可以替代zend商业化的产品。php本身的pecl扩展库也是相当的活跃,远远胜于zend本身的那几个商业化产品。
>> 路漫漫, 其修远. 思考下面的代码, 从php文档的某地方挑出来的. 它將做什么?
抑错打开一个文件句柄,这有什么呢?作者是想说他很费解,你去读读scala底层的代码,我看你是要去自杀了。
>> 如果php使用 --disable-url-fopen-wrapper编译, 它將不工作. (文档没有说, 不工作是什么意思; 返回 null, 抛出异常?)
>> 如果 allow_url_fopen 在 php.ini 中禁用, 也將不工作. (为什么? 无从得知.)
这两个为什么在新版本中禁用,事实上php wiki已经详细说明了,你如果没看到,不知道,我也不想告诉你为什么。
>> 由于 @ , non-existent file 的警告將不打印.
抑错的目的为了保障迅速解决某些实际问题,实际上你完全可以is_file(),然后抛出错误。哪个语言不是这么干的呢?如果你抱怨这里不抛出错误,我想说你真的2。你完全可以不用@,那你为什么要用呢?是你有病吗?
>> 但如果在php.ini中设置了scream.enabled, 它又將打印.>> 或者如果用 ini_set 手动设置 scream.enabled.
>> 但, 如果 error_reporting 级别没设置, 又不同.
php.ini的设置,任何团队,或者某个个人,以php开发主,一定会选择某个固定的php.ini,谁没事乱搞拼命的切换服务器的php.ini闹着玩?php.ini只是提供了一个可配置的环境给你,你自己根据自己的配置习惯,选择一套开发模式就好,你自己决定是不是抑错,是不是报错就好,这又有什么好埋怨?难道你用java开发,一会搞jdk 1.6,一会又试试jdk1.7,一会搞搞32bit,一会搞搞64bit,这不是有病吗?有本事的,你朝微软大喊,你丫有病啊,集成这么多特性到c#。
>> 该语言充满了全局和隐似状态. mbstring 使用全局字符编码. func_get_arg 之类的看起来像正常的函数, 但是只对当前正在执行的函数操作. error/exception 处理默认是全局的. register_tick_function 设置了一个全局函数去运行每个 tick(钩子?) ---- 什么?!
我觉得这完全就是神经病一样的言论。同理如上,你可以设定一个默认的php环境,而后再根据你的实际需要去做。如果你完全知道自己要怎么做,要做什么,你可以忽略大部分你不喜欢的东西。
>> 没有任何线程支持. (不奇怪, 因为上面已给出.) 加之缺乏内建的 fork (下面提到), 使得并行编程极其困难.
cgi模式下,php的线程是不在php编程范围之内的。这样处理也简化了很多东西,与其说php需要线程,不如说php需要其他支持线程的东西来支撑。我真的不认为,那些动不动张口闭口说线程的人,所要实现的功能,真的非要用到线程来实现。再说了,有本事,你用c\c++做去,用php调用就好了。这有什么问题呢?
再说了,pecl库有libevent的封装,你不知道?
>> json_decode 对不正确的输入返回 null, 尽管 null 也是一个 json 解码的合法对象 -- 该函数极不可靠, 除非你每次使用后都调用 json_last_error.
我用json_decode函数多年,几乎没碰到过任何问题,限制输入输出,这是做web本身就要严格去执行的一个金科玉律,你在这里埋怨json解析不对,你检查了输入输出没有?为什么会有异常的数据被json_decode。这才是根本解决问题的思路。
>> 如果在位置0处找到, array_search , strpos, 和其它类似的函数返回0, 但如果都没有找到的话. 会返回 false
这真的是充分显示了,你没好好看文档。0表示其从起始位置匹配,false表示为完全不匹配,你自己不好好的看文档,也不好好了解==和===的区别,strpos() == false,你一定出事。你怪得了谁,学一个语言不看文档,却在这里乱叫乱嚷。
>> 在c中, 函数如 strpos 返回 -1, 如果未找到. 如果你没检查这种情况, 却试着以下标使用它, 那將可能命中垃圾内存, 程序会崩溃. (也许吧, 这是c. 谁泥马知道. 我确定至少有工具处理它)
>> 话说, python中, 等效的 .index 方法將抛出一个异常, 如果元素没找到的话. 如果你不检查该情形, 程序將崩溃.
>> 在php中, 该函数返回 false. 如果你把 false 作为下标使用, 或者用它做其他事情, php会默默的將它转成0, 但除了用于 === 比较. 程序是不会崩溃的; 它將执行错误的逻辑, 且无任何警告, 除非你记得在每个使用 strpos 和其它类似函数的地方包含正确的样版处理代码.
你怎么不去说说,java里面需要用什么eq什么狗屁的函数去检测两个对象是否相等,这是如何恶搞和傻q的做法。
每个语言都有自己的模式,既然你懂得了c、python,又有什么还埋怨php的,这根本就是你内心轻视php,而没有认真的好好看看文档。并没有任何一个php的教程说,php主要使用c模式,只是你自己的主观臆断而已。
>> foo == true , 和 foo == 0... 但, 当然 true != 0.
>> == 会將两边转成数字, 如果可能的话, 这意味着它將转成 floats 如果可能. 所以大的16进制字符串(如, password hashes) 可能偶然会比较成 true , 尽管它们不一样. 就连 javascript 都不会这样做.
>> 由于某些原因, 6 == 6, 4.2 == 4.20, 和 133 == 0133. 但注意 133 != 0133, 因为 0133 是八进制的.
>> === 比较值和类型... 除了对象, 只有两边实际上是同一对象才为 true ! 对于对象, == 比较值(或每个属性)和类型, 这又是 === 比较任何非对象类型的行为. 好玩吗?
操作符的问题,php是有些特例,但是也不见的所有语言都很好的解决了==和===的问题。你所要做的,就是去了解,去测试,就好了,怪叫不解决任何问题。
只要记住一样事情,===是严格类型检查,而类型不是class,严格意义上,php、java、c#都是面向类型而伪装成面向对象的。如果搞不清面向类型和面向对象,你就别埋怨这方面的问题。所以php、java、c#,在处理这些方面都会存在同样蹩脚的状况。
>> [] 下标操作符也可以拼写成 {}.>> [] 可以用于任何变量, 不光是字符串和数组. 它返回 null , 无错误警告.
>> [] 仅能获取单个元素.
官方文档推荐做法是[],你偏要用{},我没办法。
使用[]如果不存在,是会报错的,返回null,无错误,是因为关闭了报错。
只能拿单个元素,又不止php,这又什么好说的?
>> foo()[0] 是个语法错误. (已在 php 5.4 中修复)
这是一个语言特性支持的问题,不是一个语法的错误。c#、java、php同样存在缺乏静态类继承的问题,但是php增加了static关键字的支持。不了解的同学,我也不想解释。
>> 不像(从字面上看)任何其它语言都有的类似的操作符, ?: 是左结合的. 因此:
用switch不是会更加省事和易明吗?你这样写,是为了优雅还是为了证明你牛逼?
>> 无法声明变量. 当第一次使用时, 不存在的变量会被创建为 null 值.
多数教程都会建议使用一个变量先初始化一个变量,我会建议建议:isset()一个变量,会让你的代码更加安全。
>> 全局变量在使用前, 需要 global 声明. 这是根据上面得出的自然结果, 因此这是个完美的理由, 但, 如果没有显示的声明, 全局变量甚至无法读取 -- php 將悄悄的创建一个局部同名变量取代它. 我还没见过其它语言使用类似的方法处理范围问题.
不懂装懂了不是?
1 $globals['abc'] = 123;
2
3 function test() {
4 global $abc;
5 unset($abc);
6 }
7 test();
8
9 var_dump(isset($globals['abc'])); // 这里输出什么?
zend framework的使用规范里面已经强调了这个问题。
>> 没有引用. php所谓的引用是个真正的别名; 这无疑是一种倒退, 不像 perl 的引用, 也没有像 python 那样的对象标识传递.
我不知道具体python和perl的引用是如何,我也不觉得php的引用存在任何问题。
......
......
好了,够了,我真的不想再一一的去列举和反驳了,我纵观全文,发现以下几点:
1、作者是一个神经质,极端的竭斯底里和吹毛求疵。
2、不懂装懂,列举不同语言来说明php的不是,但只说明他自己本身没有好好看php的文档说明。
3、作者是个自恋狂,拿着那仅有的经验和经历来说是,就算是在c里面==和===也是要特别小心对待的。
4、既然作者极端的埋怨php,其实我觉得他不如直接的去学别的语言好了,埋怨有用吗?
我是从ruby转做php的,最初上手的时候,也觉得这这那那不习惯。但是php并没有他说的那么糟糕,而且php是很自由的,要怎么做,你自己完全可以选择。选好一种正确的模式,你就可以完全忽视你认为不喜欢的东西。
后来到我需要使用java了,我真的觉得java(不是jdk)是这个世界上最傻帽,最俗不可耐,却又非要装得冠冕堂皇的语言,尤其是那一层有一层白痴一样的继承,所以我决定不使用java,而使用scala。
如果你真的那么计较缺失的地方,你别用php好了,说这些有用吗?
总结
我知道红薯,我也看过大东的文章,都是有一定经验的开发员,什么是有水平的文章,什么是垃圾喷子(就算是骂,也得是有水平的骂,有本事翻出源代码来说事),我想,如果就他们自己本身的熟悉的语言,他们一定能一眼洞悉。他们不了解php,我觉得情有可原。
可是问题又在于,这样一篇文章,本身就破绽百出,他所说的那些许多个问题,已经充分的暴露了他本身都没有好好的去了解php,也没有好好的去读php的官方文档,这样一个什么都不认真了解,半桶水的傻帽写的文章,却大摇大摆的拿来做首页置顶,然后冠冕堂皇的给自己一个说法:警惕众多php的开发人员避免发生同样类似的错误。大侠,你是周星驰,来搞笑的吗?
同时,oschina,作为一个面向全面开源而言,就你们两个本身,又能够了解多少东西呢?大家无非也就是在自己所熟悉的领域内摸爬滚打,你连php都不了解,你凭什么说你要用这篇文章告诫广大php的开发人员呢?
还有告诉那些回帖里,说什么用这个狗屁文章来做一个警醒的人,回去好好认真的读读php的文档,回去好好看看php的wiki,雪候鸟(http://www.laruence.com/)和胖胖(http://www.phppan.com/)的博客都认真看看,比你在这里跟帖有意义得多。
好了,这会是我在osc的封笔之帖,我是不会恢复我在osc的所有文章的,忙完这段时间,我会另外申请域名开通个人的博客,稍迟我会公布,如果觉得在下的文章还有点意思的朋友请保持关注。
谢谢捧场!