为什么PHP中不允许“传统”类型提示?

时间:2011-01-21 00:46:32

标签: php type-hinting

刚刚发现PHP中允许type-hinting,但不能用于整数,字符串,bool或浮点数。

为什么PHP不允许对整数,字符串等类型进行类型提示??

3 个答案:

答案 0 :(得分:10)

自PHP 7.0起,支持boolintfloatstringscalar types RFC中添加了支持。有两种模式:弱和严格。我建议阅读RFC以完全理解差异,但基本上类型转换只发生在弱模式下。

鉴于此代码:

function mul2(int $x) {
    return $x * 2;
}
mul2("1");

在弱模式下(这是默认模式),这会将"1"转换为1

要启用严格类型,请在文件顶部添加declare(strict_types=1);。在严格模式下,将发出错误:

  

致命错误:传递给mul2()的参数1必须是整数类型,给定字符串

答案 1 :(得分:9)

PHP的松散类型,您的“原始”类型会根据它们使用的上下文自动type-juggled。类型提示不会真正改变它,因为字符串可以用作int,反之亦然。类型提示只对数组和对象等复杂类型有帮助,这些类型不能干净地作为整数,字符串或其他基元进行处理。

换句话说,由于PHP没有特定类型的概念,你不能在某处需要 int 因为它不知道 int 到底是什么是。另一方面,对象是某种类型的,因为 MyClass 不能与 MyOtherClass 互换。


仅供参考,以下是尝试在这些类型之间进行转换时所发生的情况(不是详尽的列表):

转换为对象ref
“如果将对象转换为对象,则不会对其进行修改。如果将任何其他类型的值转换为对象,则会创建 stdClass 内置类的新实例。 value为NULL,新实例将为空。数组转换为具有按键和相应值命名的属性的对象。对于任何其他值,名为标量的成员变量将包含该值。“

对象为int / float ref
未定义的行为

对象布尔ref
在PHP5中,始终为TRUE

对象到字符串ref
如果适用,将调用对象的__toString() magic method

对象到数组ref
“如果一个对象被转换为一个数组,结果就是一个数组,其元素是对象的属性。这些键是成员变量名,有一些值得注意的例外:整数属性是不可访问的;私有变量的类名前置于变量名;受保护变量在变量名前加上'*'。这些前置值在任何一方都有空字节。这可能会导致一些意外行为。“

数组到int / float ref
未定义的行为

数组到布尔ref
如果数组为空(即没有元素),则计算结果为FALSE - 否则为TRUE。

数组到字符串ref
字符串“Array”;使用print_r()var_dump()打印数组的内容

阵列到对象ref
“数组转换为具有按键和相应值命名的属性的对象。”

答案 2 :(得分:1)

将其称为“类型提示”是不恰当的。 “提示”意味着它是一些可选的输入,仅仅提示而不是要求,但是类型化的函数参数根本不是可选的 - 如果你给它错误的类型,你会得到致命的错误。称之为“类型提示”是一个错误。

现在为什么PHP中的函数参数没有原始类型的原因。 PHP在原始类型之间没有障碍 - 即string,integer,float,bool - 或多或少可以互换,你可以拥有$a = "1";然后echo $a+3;并获得4。所有内部函数也都以这种方式工作 - 如果函数需要一个字符串并且你传递一个整数,它就会被转换为字符串,如果函数需要一个浮点数并得到一个整数,它就会转换成浮点数等。这与对象类型不同 - 例如SimpleXMLElementDirectoryIterator之间没有任何转换 - 两者都没有,它没有任何意义。

因此,如果引入接受整数1而不是字符串1的函数,则会在内部函数和用户函数之间创建不兼容性,并为任何假定它们几乎相同的代码创建问题。这将是PHP程序行为方式的一个重大变化,并且需要使用这些函数在所有代码中传播此更改 - 否则您在“严格”和“非严格”代码之间转换时会冒错误。这意味着类型变量,类型属性,类型返回值等的必要性 - 大变化。而且由于PHP不是一种编译语言,因此你不会受到静态类型控制的好处,而且它的缺点是 - 你只会带来不便,但不会增加安全性。这就是PHP中不接受参数输入的原因。

还有另一种选择 - 强制类型,即类似于内部函数的行为 - 在类型之间进行转换。不幸的是,这个不满足严格打字的支持者,因此到目前为止没有找到共识,因此没有一个存在。

另一方面,对象类型从来没有争议 - 显然它们之间没有转换,没有代码假定它们是可互换的,并且检查只能对它们严格,内部和外部函数都是如此。因此,引入严格的对象类型不是问题。