在PHP 8.1中,以下代码适用于以前的版本:

class Example implements Countable {
    public function count() {
        return 42;
    }
}

引发弃用通知:

不推荐使用:Example::count()的返回类型应该与Countable::count():int兼容,或者应该使用#[\ReturnTypeWillChange]属性来临时 suppress 通知

这意味着什么,我应该如何修复它?

推荐答案

Background: Return types and covariance

自PHP7.0以来,可以指定函数或方法的return type,例如function example(): string,以指示返回字符串的函数.这形成了一个其他代码可以依赖的contract.

例如,这个类promise getList方法将返回某种Iterator:

class Base {
    public function getList(): Iterator {
       // ...
    }
}

编写调用代码时可以知道,如果$foo instanceOf Base为真,那么$foo->getList() instanceOf Iterator也将为真.

如果扩展该类,可以指定same返回类型或a more specific返回类型(称为"协方差"的规则),调用代码的假设仍然为真:

class SubClass extends Base {
    public function getList(): DirectoryIterator {
        // ...
    }
}
$foo = new SubClass;
var_dump($foo instanceOf Base); // true
var_dump($foo->getList() instanceOf Iterator); // true

但是,如果指定different返回类型,或者no return type at all,那么假设就不成立了,所以PHP不允许这样做:

class NotPossible extends Base {
    public function getList(): bool {
        return false;
    }
}
// Fatal error: Declaration of NotPossible::getList(): bool must be compatible with Base::getList(): Iterator
// If the error didn't happen...
$foo = new NotPossible;
var_dump($foo instanceOf Base); // would be true
var_dump($foo->getList() instanceOf Iterator); // would be false!

Backwards compatibility and deprecation

如果向现有类或接口添加一个返回类型,则扩展或实现must的每个类也会发生更改,否则它将给出与上述NotPossible示例相同的错误.

PHP8.0中增加了Union Types,可以指定大多数内部函数和方法的返回类型;但为任何未标记为final的类或接口方法指定它会立即 destruct 大量代码.

因此,取而代之的是,增加了"暂定"退货类型的概念:正确的退货类型已记录在案,但通常会出现错误的是问题中显示的弃用通知.

The #[\ReturnTypeWillChange] attribute

另外一个问题是,许多代码需要能够在多个版本的PHP上运行,而且添加的一些返回类型在8.0之前的版本中无效.因此,为了在代码中指示对返回类型的planned更改,可以添加特殊的attribute #[\ReturnTypeWillChange].这看起来像是对旧版本PHP的 comments ,但告诉PHP8.1不要提出反对通知.然后,一旦不需要支持旧版本的PHP,就可以修复返回类型.

What should you do now?

首先,仔细阅读信息,找出需要更改的方法,以及正确的返回类型.在上面的例子中:

返回示例的类型::count()...

这说明Example类的count方法需要改变...

... 应该与Countable::count()兼容:int...

... 预期的返回类型是int,如Countable接口上定义的

接下来,决定你能做什么:

  • 你的类是否已经返回了正确的类型?在我们的示例中,是的,42对于int的返回类型有效.
  • 您能安全地更改方法的返回类型吗?如果你正在开发自己的应用程序,答案可能是"是的",只要你更新了extend个这样的类.如果您正在处理用户可能已经扩展了该类的库代码,则需要考虑对它们的影响.

如果你认为它是安全的,你可以简单地按照通知中所示的add the return type:

class Example implements Countable {
    public function count(): int {
        return 42;
    }
}

如果您需要支持旧版本的PHP,或者尚未更新代码的用户,您可以取消以下通知:

class Example implements Countable {
    #[\ReturnTypeWillChange]
    public function count() {
        return 42;
    }
}

需要注意的是,内部返回类型可能是enforced in PHP 9.0,因此请确保您有一个可靠的计划来更改使用此属性标记的方法.

Php相关问答推荐

提交表格后的重定向不起作用

如果活动订阅者的购物车中有订阅项目,则在WooCommerce签出中显示通知

自定义通知在Woocommerce我的帐户自定义端点页面上不起作用

wp_enqueue_scripts not loading(基于类的插件)

Msgraph-sdk-php v2如何从返回对象中获取数据?

在Google云存储对象上从PHP设置缓存控制TTL会更改错误的元数据

PHP日期操作,将多个日期输出为格式化字符串

致命错误:未捕获错误:Google\Auth\HttpHandler\HttpHandlerFactory::build()

在内部API请求之后,在响应客户端之前,是否忘记了PHP中的Header()?

laravel中获取的数据会自动更改时间戳值

在Symfony 6.4中将工作流动态添加到服务

如何在汇总表构建器中操作LALAVEL细丝Sum::Make()值

升级到PHP 8.2后无法删除cURL Cookie文件

用GUZLE模拟Read_Timeout

Mockery在模拟Redis连接时抛出错误:Mockery\Exception\BadMethodCallException

$this->;db->;update();CodIgnitor中的功能不工作

调度程序不发送任何消息

我的功能以舒适的方式显示数组 struct

使用 --exclude-dir 选项从 PHP 执行 grep 时出现问题

如何在 php/laravel 中获取元素在数组中的位置