驳《五大受损 全面解析PHP的糟糕设计》——为PHP正言

出处:http://www.oschina.net/question/57579_50368


《五大受损 全面解析PHP的糟糕设计》,原文地址: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的所有文章的,忙完这段时间,我会另外申请域名开通个人的博客,稍迟我会公布,如果觉得在下的文章还有点意思的朋友请保持关注。

谢谢捧场!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值