Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/237.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php函数实现重写不可为空的参数_Php_Type Hinting - Fatal编程技术网

php函数实现重写不可为空的参数

php函数实现重写不可为空的参数,php,type-hinting,Php,Type Hinting,我今天用PHP(至少7.1和7.2)遇到了这个问题,代码如下: 所以我有一个接口(InterfaceA),它有一个需要字符串的方法。此参数不可为null,因为如果需要,我会将其指定为: public function test(?string $testString): void; 但是在实现类(SomeClassA)中,我可以用默认值null覆盖参数定义,这会导致我在接口中不希望出现的行为 所以我的主要问题是:为什么这是可能的?当然,我们需要在代码评审中检查这一点,但这很容易被忽略 我试图

我今天用PHP(至少7.1和7.2)遇到了这个问题,代码如下:

所以我有一个接口(InterfaceA),它有一个需要字符串的方法。此参数不可为null,因为如果需要,我会将其指定为:

public function test(?string $testString): void;
但是在实现类(SomeClassA)中,我可以用默认值null覆盖参数定义,这会导致我在接口中不希望出现的行为

所以我的主要问题是:为什么这是可能的?当然,我们需要在代码评审中检查这一点,但这很容易被忽略


我试图寻找导致这种行为的原因,但找不到解释。可能我的搜索条件已关闭。

PHP允许您在实现中设置或修改默认值,只要类型匹配即可。需要注意的是,所有提示类型都允许null作为默认值

如果有人找到了对此的具体解释,那么我可以更新这个答案,但在7.1之前,声明可选参数的唯一方法是指定一个默认值null。
?字符串
语法不存在,因此此行为可能源于此,并且为了向后兼容而仍然存在

如果尝试设置默认值(例如整数),您将看到一条错误消息,显示:

Fatal error: Default value for parameters with a string type can only be string or NULL

到目前为止,开发人员似乎有责任确保实现的默认值与可为null或不可为null的接口声明相匹配。

在PHP7.2中实现了参数类型。这是某种相反的变化。遗憾的是,PHP目前不支持参数的反向变化,但草案中还有和rfc来支持这一点

主要思想是:如果您有一个子类,那么可以在子类中使用“更广泛”的参数类型。对于返回类型,opsite是有效的(协方差)

如果这是一个好的或坏的做法,取决于你的需要。据我所知,其他语言也有同样的表现

为了进一步阅读,有两个rfc:

  • 参数类型加宽:

  • 协变返回和逆变参数(草稿)


超类应该由其子类替换。所以子类必须能够完成超类所做的一切,但它也可以做得更多


在您的示例中,超类/接口不知道如何处理null。但是子类可以,这很好,因为超类的用户只会传递非空值,因为他们认为超类契约有效。

我实际上不知道7.2启用了这一点,但我认为这与OP的要求无关。声明中的类型没有更改或加宽,只是指定了默认值。可以为Null的类型比不可以为Null的类型更宽-不管是否有默认值,但该行为不会随所引用的rfc而改变。自从引入类型暗示以来,始终允许使用默认值null。(你的回答不能解释7.0和7.1的这种行为)@Philipp谢谢你的回答,但我想我必须同意Devon的观点,即这种行为的原因不是加宽。主要是因为它也出现在7.1中。成为PHP向后兼容特性之一似乎更有可能。不过这真的让我很恼火;)谢谢你的回答。这似乎是PHP为保持向后兼容性完好无损所做的许多事情之一。我只是希望能有更好的记录。@RickVH,对。我认为大多数语言都允许空值来代替其他类型,所以这并不少见。Philip指出了在7.2中实现的rfc,看起来您的担心会更糟,因为它们实际上可以使接口的类型为null,并允许传递除string/null以外的类型,因此,今后,如果开发人员想要保持接口的真实性,他们将承担更多的责任。我同意。但这很好。我会把这个帖子作为我问题的答案。非常感谢@Phillip指出情况会变得更糟。
Fatal error: Default value for parameters with a string type can only be string or NULL