PHP 类型提示 - 代码与注释
Posted
技术标签:
【中文标题】PHP 类型提示 - 代码与注释【英文标题】:PHP type hinting - code vs. annotations 【发布时间】:2015-02-18 07:06:14 【问题描述】:php 5 可以做一些(有限的)type hinting,然而,在我看来,在现实世界的项目中,类型通常在 doc cmets 中描述。例如,而不是这个:
/**
* Test method
*/
function test(SomeType $param1)
...
会有更常见的
/**
* Test method
*
* @param SomeType param1
*/
function test($param1)
...
这两种方法的优缺点是什么?如果我认为 PhpDoc 方法更常见的假设是正确的,那为什么呢?为什么人们不更多地利用内置语言功能?
编辑:第三种选择是结合使用这两种方法:
/**
* Test method
*
* @param SomeType param1
*/
function test(SomeType $param1)
...
但是,我个人并没有经常看到它使用过(查看 Symfony 或 PHPUnit 之类的库),老实说,这似乎也做一些工作并没有太多额外的好处。也许这就是为什么它不经常看到的原因。
【问题讨论】:
首先,您也可以写@param SomeType $param1
。它会阻止您传递除SomeType
之外的任何其他类型。第二个只会在 phpDoc 中显示,但 $param1
可以是任何类型。
好点,我已经更新了 OP。
如果您使用的是具有自动完成功能的 IDE,您还可以键入内联提示,这有时会派上用场:/* @var $somevar \YourNamespace\YourObject */
郑重声明:PHP 已经进化了。它的新版本具有更强大的提示功能(可以处理标量、数组返回类型、空值......)。
【参考方案1】:
我个人会同时使用两者。
第一个选项适用于控制传递给方法的对象。第二个通常可以由任何现代 IDE 自动添加,它使您的代码更具可读性。
【讨论】:
【参考方案2】:第一件事:PHP 类型提示的提示能力与 PHPDoc 不同。区别是(至少):
标量类型。在 PHP 7.1 之前,您不能提示标量类型,但没有什么可以阻止您进行提示
/**
* @param string $param Param description
*/
提示数组。在 PHPDoc 中,您可以提示,该参数(或返回值)是一些东西的数组。应该是:
/**
* @param ClassName[] $param Param description
*/
这意味着 - ClassName
的实例数组。这在返回类型方面非常有用(因为 IDE 可能会在该数组的迭代中替换方法,因此,您会知道您是否在做正确的事情)。但是,在 PHP 中,您只能将其键入为
function functionName(array $param) /*...*/
所以不可能知道数组的实际元素是什么。供您参考,有一个对应的 RFC 用于将类型提示作为某些元素的数组,目前已被拒绝 - 但将来这种可能性可能会出现在 PHP 中。
但是,另一方面,使用 PHP 类型提示仍然是不同的事情,通常你应该两者都做 - 所以,如果可以在 PHP 中以某种方式提示(如上面的数组示例) - 这样做,并将 PHPDoc 块添加为好吧。 PHP typehint 允许您在语言级别强制执行行为,而 PHPDoc 只是“信息”源,它仅服务于信息目标,不能防止传递非法参数类型。
【讨论】:
好点,我只是不确定最后一段。虽然从理论上讲,同时拥有这两种类型的提示确实感觉更好,但它在实践中可能不会增加太多价值,至少我是这样看的,如果你看看现实世界的项目,我似乎不是一个人。 但它增加了。如果你有一些实例的数组,你会在 PHP 和 PHPDoc 中输入提示,所以你至少不能将非数组传递给函数(在语言级别),另一方面,你'将能够使用 IDE 替换。所以 - 是的,PHP 类型提示是有限的,但你应该尽可能多地使用它们来缩小传入参数类型,如果你知道它的上下文 类型在执行时的实际执行是将类型提示放入代码本身的原因。把它放在 PHPDoc 中是常见的做法,主要是因为 PHPDoc predates PHP typehinting,因此 PHPDoc 有一个类型 documented 是你当时可以做的最好的方式知道代码期望什么的用户。文档生成器通常会假定 PHPDoc 信息是真实信息并使用它,但如果没有给出 PHPDoc,它们也会退回到代码本身。 IDE 通常遵循相同的行为。以上是关于PHP 类型提示 - 代码与注释的主要内容,如果未能解决你的问题,请参考以下文章