Reference: Return Type of ... Should Either Be Compatible with ..., or the #[\Returntypewillchange] Attribute Should Be Used

Reference: Return type of ... should either be compatible with ..., or the #[\ReturnTypeWillChange] attribute should be used

Background: Return types and covariance

Since PHP 7.0, it has been possible to specify the return type of a function or method, such as function example(): string to indicate a function that returns a string. This forms a contract that other code can rely on.

For instance, this class promises that the getList method will return some kind of Iterator:

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

Calling code can be written knowing that if $foo instanceOf Base is true, then $foo->getList() instanceOf Iterator will also be true.

If you extend the class, you can specify the same return type, or a more specific return type (a rule known as "covariance"), and the calling code's assumption will still be true:

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

But if you specify a different return type, or no return type at all, the assumption breaks, so PHP won't allow you to do it:

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

If you add a return type to an existing class or interface, every class extending or implementing must also be changed, or it will give the same error as in the NotPossible example above.

With the addition of Union Types in PHP 8.0, the return types of most internal functions and methods can be specified; but specifying it for any class or interface method not marked final would have immediately broken a lot of code.

So, instead, the concept of a "tentative" return type was added: the correct return types were documented, but what would normally be an error is instead the deprecation notice shown in the question.

The #[\ReturnTypeWillChange] attribute

The extra problem is that a lot of code needs to be able to run on multiple versions of PHP, and some of the added return types aren't valid in versions before 8.0. So, to indicate a planned change to the returned type in your code, you can add the special attribute #[\ReturnTypeWillChange]. This looks like a comment to older versions of PHP, but tells PHP 8.1 not to raise the deprecation notice. Then, once you don't need to support older versions of PHP, you can fix the return type.

What should you do now?

Firstly, read the message carefully to find out which method you need to change, and what the correct return type is. In the example above:

Return type of Example::count() ...

This says the count method on the Example class needs changing ...

... should either be compatible with Countable::count(): int ...

... and the expected return type is int, as defined on the Countable interface

Next, decide what you can do:

  • Is the code that needs to change in a library or extension written be someone else? Check if there is a new version available. Since this is only a deprecation, it's OK to ignore it and give the author time to fix it.
  • Does your class already return the correct type? In our example, yes, 42 is valid for a return type of int.
  • Can you safely change the return type of the method? If you're working on your own application, the answer is probably "yes", as long as you update classes that extend this one. If you're working on library code where users might have extended this class, you will need to consider the impact on them.

If you decide it's safe, you can simply add the return type as shown in the notice:

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

If you need to support older versions of PHP, or users who won't have updated their code yet, you can temporarily suppress the notice:

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

It's important to note that the internal return types will probably be enforced in PHP 9.0, so make sure you have a solid plan to change methods you mark with this attribute.

Message: Return type of CI_Session_files_driver::open($save_path, $name) should either be compatible with

For anyone else that comes across this error, I also experienced it after upgrading to PHP 8.1. The only way I could find to "fix" it was by adding #[\ReturnTypeWillChange] before the open, read, write, close, destroy and gc functions in /system/libraries/Session/drivers/Session_files_driver.php. For example:

#[\ReturnTypeWillChange]
public function open($save_path, $name)
{
...

composer and laravel 7 not working with php 8.1

I had the same issue with the newest xampp, all i did was go back to 7.4.26 and now the installations of 6-7 work fine.

Laravel issue after upgrade host to php 8.1

I resolve the problem with the upgrade laravel from 7 to 8



Related Topics



Leave a reply



Submit