设为首页收藏本站

LUPA开源社区

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

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

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

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

数字

>>    Integers 在32位平台是是有符号32位数. 不像PHP的同时代者, 没有自动 bigint 提升. 因此你的数学运算可能会由于CPU体系结构结果不一样. 你唯一选择大整数的方式是使用 GMP 或 BC 包装函数. (开发者可能已经建义加入新的, 单独的,64位类型. 这真是疯了.)

>>    PHP支持八进制数语法, 以0开头, 因此如 012 是10. 然而, 08变成了0. 8(或9)和任何接下来的数字消失了. 01c是个语法错误.

>>    pi 是个函数. 或者有个常量, M_PI. 

>>    没有幂操作符, 只有 pow 函数.

文本

>>    无Unicode支持. 只有ASCII工作是可靠的, 真的. 有个 mbstring 扩展, 上面提过的, 但会稍被打击.

>>    这意味着使用内建的string函数处理UTF-8文本会有风险.

>>    相似的, 在ASCII外, 也没有什么大小写比较概念. 尽管有扩展版本的大小写敏感的函数, 但它们不会认为 é 等于 É.

>>    你不能在变量中内插keys , 如, "$foo['key']"是个语法错误. 你也不能 unquote it (这样会产生警告, 无论什么地方!), 或使用 ${...}/{$...}

>>    "${foo[0]}"是对的. "${foo[0][0]}"是个语法错误. 糟糕的拷贝类似 Perl 的语法 (两个根本不同的语议)?

数组

    呕, 骚年.

>>    这家伙扮演list数据类型, 操作hash, 和排序set, 解析 list, 偶尔会有些奇怪的组合. 它是怎样执行的? 以何种方式使用内存? 谁知道? 不喜欢, 反正我还有其它的选择.

>>    => 不是操作符. 它是个特别的结构, 仅仅存在于 array(...) 和 foreach 结构中.

>>    负值索引不工作, 尽管 -1 也是个和0一样的合法键值.

>>    尽管这是语言级的数据结构, 但没有简短语法; array(...)是简短语法. (PHP 5.4 带来了"literals", [...].) 

>>    => 结构是基于 Perl , Perl允许 foo => 1 而不用引号.  在PHP中, 你这么做会得到警告; 没有无需引号创建 hash 字符串键值的方式.

>>    数组处理函数常常让人迷惑或有不确定行为, 因为它们不得不对 lists, hashes, 或可能两者的结合体做运算. 考虑 array 分组, "计算arrays的不同部分". 

1 $first  = array("foo" => 123, "bar" => 456);
2  
3 $second = array("foo" => 456, "bar" => 123);
4  
5 echo var_dump(array_diff($first, $second));

    这段代码將做什么? 如果 array_diff 將参数以 hashes 看待, 它们明显是不同的; 相同的keys有不同的值. 如果以list看待, 它们仍然是不同的; 值的顺序不同.

    事实上 array_diff 认为它们相等, 因为它以 sets 对待: 仅仅比较值, 忽略顺序.

>>    同样, array_rand 随机选择keys时, 也有奇怪的行为, 这对大多数需要从列表中挑出东西的用例没什么帮助. 

    尽管大量PHP代码依赖key的顺序:

1 array("foo", "bar") != array("bar", "foo")
2  
3 array("foo" => 1, "bar" => 2) == array("bar" => 2, "foo" => 1)

>>    如果两个数组混合的话, 会发生什么? 我留给读者自己弄清楚. (我不知道)

>>    array_fill 不能创建0长度的数组; 相反它会发出警告并返回 false.

>>    所有的(很多的...) 排序函数就地操作而什么都不返回. 想新建一个已排序数组的拷贝, 没门; 你不得不自己拷贝数组, 然后排序, 然后再使用数组.

>>    但 array_reverse 返回一个新数组.

>>    一堆被排序的东西和一些键值对听起来像是个某种强大的处理函数参数的方式, 但, 没门.

非数组 

>>    标准库包含 "快速哈希", "特定的强类型"的hash结构OO实现. 然, 深入它, 有4类, 每种处理不同的键值对类型组合. 不清楚为什么内建的数组实现不能优化这些极其普通情况, 也不清楚它相对的性能怎样.

>>    有个 ArrayObject 类 (实现了4个不同的接口) , 它包装数组让它看起来像对象. 自定义类可以实现同样的接口. 但只有限的几个方法, 其中有一半不像内建的数组函数, 而内建的数组函数不知道怎样对ArrayObject或其它的类数组的类型操作. 

函数

>>    函数不是数据. 闭包实际上是对象, 但普通的函数不是. 你甚至不能通过它们裸名称引用它们; var_dump(strstr) 会发出警告并猜测你的意思是字符串字面量, "strstr". 想辨别出字符串还是"函数"引用, 没门. 

>>    create_function 基本上是个 eval 的包装者. 它用普通的名字创建函数并在全局范围安装它(因此永远不会被垃圾回收---不要在循环中使用!). 它实际上对当前上下文一无所知, 因为它不是闭包. 名字包含一个 NUL 字节, 因此永远不会与普通函数冲突 (因为如果在文件的任何地方有 NUL的话,  PHP 的解析器会失败).

>>    Declaring a function named __lambda_func will break create_function—the actual implementation is to eval-create the function named __lambda_func, then internally rename it to the broken name. If __lambda_func already exists, the first part will throw a fatal error.


酷毙
1

雷人

鲜花

鸡蛋

漂亮

刚表态过的朋友 (1 人)

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

最新评论

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

返回顶部