设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客

挑刺PHP:全面解析PHP的糟糕设计

2012-4-22 10:25| 发布者: joejoe0332| 查看: 15669| 评论: 1|原作者: OSCHINA|来自: OSCHINA

摘要: 译者注:这篇文章很长,而且可能读起来很乱,很难懂 前言 我的脾气古怪. 我会抱怨很多东西. 这个星球上大多数技术我都不喜欢. PHP不仅使用起来尴尬, 还有要嘛我想要的不适合, 要嘛不是最令人满意, 要嘛违背我的信 ...

PHP

语言核心

  CPAN被称为 "Perl的标准库". 这并没有对Perl的标准库做过多说明, 但它蕴含了健壮的核心可以构建强大的东西的思想.

基本原则


PHP最初很明确的是为非程序员设计的(言外之意,  非专业程序); 根源已经很难脱离. 从PHP 2.0 文档中挑选出来的对话:

    一旦你开始为每个类型区分不同的操作符, 你就开始使用语言变得复杂了. 例如, 你不能为strings使用 '==', 你现在必须用 'eq'. 我没看出这点来, 特别是那些类似PHP的脚本语言, 它们大多数相当简单而多数情况下, 作为非程序员, 只想要一门包含少量基本逻辑语法的语言, 而不想付出过多学习曲线.

    >>    PHP 为保持前进不惜代价. 什么都有比没有好.

    >>    这不是个正确的设计原则. 早期的PHP受Perl影响; 大量的标准库参考C使用 "out" 参数; OO部分的设计像C++和Java.

    >>    PHP从其它语言中引入大量的灵感, 但对那些熟知其它语言的人, 仍然难以理解. (int)看起来像 C, 但是 int 并不存在. 命名空间使用 \. 新的数组语法使用 [key => value], 不同于任何其它语言定义hash字面量的形式.

    >>    弱类型(例如, 默默的自动在 strings/mumbers/等间转换)是如此的复杂.

    >>    少量的新特性以新语法实现; 大多数工作通过函数或者看起来像函数的东西完成. 除了类的支持, 这理所当然的需要新的操作符和关键字.

    >>    本页列出的问题都有官方解决方案 -- 如果你想资助 Zend 修复它们的开源编程语言的话. 

    >>    路漫漫, 其修远. 思考下面的代码, 从PHP文档的某地方挑出来的. 

1 @fopen('http://example.com/not-existing-file', 'r');

    它將做什么? 

        >>    如果PHP使用 --disable-url-fopen-wrapper编译, 它將不工作. (文档没有说, "不工作"是什么意思; 返回 null, 抛出异常?)

        >>    注意这点已在 PHP 5.2.5 中移除.

        >>    如果 allow_url_fopen 在 php.ini 中禁用, 也將不工作. (为什么? 无从得知.)

        >>    由于 @ , non-existent file 的警告將不打印.

        >>    但如果在php.ini中设置了scream.enabled, 它又將打印.

        >>    或者如果用 ini_set 手动设置 scream.enabled. 

        >>    但, 如果 error_reporting 级别没设置, 又不同.

        >>    如果打印出来了, 精确去向依赖于 display_errors , 再一次还是在 php.ini. 或者 ini_set中.

    我无法告诉你这个函数调用的行为, 如果没有查看编译时标志 , 服务器端配置, 和我的程序中的配置的话. 这些都是内建行为.

    >>    该语言充满了全局和隐似状态. mbstring 使用全局字符编码. func_get_arg 之类的看起来像正常的函数, 但是只对当前正在执行的函数操作. Error/exception 处理默认是全局的. register_tick_function 设置了一个全局函数去运行每个 tick(钩子?) ---- 什么?!

    >>    没有任何线程支持. (不奇怪, 因为上面已给出.) 加之缺乏内建的 fork (下面提到), 使得并行编程极其困难.

    >>    PHP的某些部分在实践中会产生错误代码.

        >>    json_decode 对不正确的输入返回 null,  尽管 null 也是一个 JSON 解码的合法对象 -- 该函数极不可靠, 除非你每次使用后都调用 json_last_error. 

        >>    如果在位置0处找到, array_search , strpos, 和其它类似的函数返回0, 但如果都没有找到的话. 会返回 false

让我们稍稍展开最后一部分.

    在C中, 函数如 strpos 返回 -1, 如果未找到. 如果你没检查这种情况, 却试着以下标使用它, 那將可能命中垃圾内存, 程序会崩溃. (也许吧, 这是C. 谁泥马知道. 我确定至少有工具处理它)

    话说, Python中, 等效的 .index 方法將抛出一个异常, 如果元素没找到的话. 如果你不检查该情形, 程序將崩溃.

    在PHP中, 该函数返回 false. 如果你把 FALSE 作为下标使用, 或者用它做其他事情, PHP会默默的將它转成0, 但除了用于 === 比较. 程序是不会崩溃的; 它將执行错误的逻辑, 且无任何警告, 除非你记得在每个使用 strpos 和其它类似函数的地方包含正确的样版处理代码.

    这真是糟透了! 编程语言只是工具; 它们是为我服务的. 这里, PHP给我布下了陷阱, 等着我跳进去, 而我不得不时刻警惕这些无聊的字符串操作和相等比较. PHP是个雷区.

我已经听过很多关于PHP解析器的故事, 它的开发者来自世界各地. 有从事PHP核心开发工作的人, 有调试PHP核心的人, 也有和核心开发者交流过的人. 没有一个故事是赞赏的.

因此不得不在这里插入一句, 因为它值得重复: PHP是个业余爱好者的社区. 极少数人设计, 为它工作, 或极少有人知道他们在做什么. (哦, 亲爱的读者, 你当然是个极品例外!) 那些成长了, 想转投其它平台的人, 使整个社区的平均水平下降. 这个, 就是这里, 是PHP的最大问题: 绝对的盲目领导盲目.

好了, 回来面对现实吧.

操作符

     == 不中用.

        >>    "foo" == TRUE , 和 "foo" == 0... 但, 当然 TRUE != 0.

        >>    == 会將两边转成数字, 如果可能的话,  这意味着它將转成 floats 如果可能. 所以大的16进制字符串(如, password hashes) 可能偶然会比较成 true , 尽管它们不一样. 就连 JavaScript 都不会这样做.

        >>    由于某些原因, "6" == "6", "4.2" == "4.20", 和 "133" == "0133". 但注意 133 != 0133, 因为 0133 是八进制的.

        >>    === 比较值和类型... 除了对象, 只有两边实际上是同一对象才为 true ! 对于对象, == 比较值(或每个属性)和类型, 这又是 === 比较任何非对象类型的行为. 好玩吗?

    比较大小也好不到哪去.

        >>    甚至行为都不一致: NULL < -1, 而 NULL == 0. 排序也因此不确定; 它依赖于在排序中比较元素的算法的顺序.

        >>    比较操作符尝试排序数组, 以两种不同的方式: 首先按长度, 然后按元素. 如果它们有相同数量的元素但不同的keys, 它们是不可比的.

        >>    对象比较比其它比较做得更多... 除了那些即不小于也不大于的对象.

        >>    为了类型更安全的 == 比较, 我们有 ===. 为了类型更安全的 < 比较, 我们有... 什么也没有. "123" < "0124", 通常, 不管你怎么做. 类型转换也无济于事.

    >>    尽管上面的举动很疯狂, 但却明确拒绝Perl's的字符串 paris 和算术运行符, PHP没有重载 +. + 就是通常的 +, 而 . 是通常的连接符.

    >>    [] 下标操作符也可以拼写成 {}.

    >>    [] 可以用于任何变量, 不光是字符串和数组. 它返回 null , 无错误警告.

    >>    [] 仅能获取单个元素.

    >>    foo()[0] 是个语法错误. (已在 PHP 5.4 中修复)

    >>    不像(从字面上看)任何其它语言都有的类似的操作符, ?: 是左结合的. 因此:

01 $arg = 'T';
02  
03 $vehicle = ( ( $arg == 'B' ) ? 'bus' :
04  
05              ( $arg == 'A' ) ? 'airplane' :
06  
07              ( $arg == 'T' ) ? 'train' :
08  
09              ( $arg == 'C' ) ? 'car' :
10  
11              ( $arg == 'H' ) ? 'horse' :
12  
13              'feet' );
14  
15 echo $vehicle;

    打印 horse.


酷毙
1

雷人

鲜花

鸡蛋

漂亮

刚表态过的朋友 (1 人)

  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部