'PHP setTime() return type not compatible but setTime() in DateTime class has no return?
I'm updating some PHP 5 code to PHP 7+ standards.
We have a AcmeDate class that extends DateTime and using setTime() is generating deprecated notices.
public function setTime($hours, $minutes, $seconds = 0, $microseconds = 0) {
parent::setTime ( $hours, $minutes, $seconds, $microseconds );
}
E_DEPRECATED Return type of AcmeDate::setTime($hours, $minutes, $seconds = 0, $microseconds = 0) should either be compatible with DateTime::setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0): DateTime, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice
I understand that DateTime::setTime() has a DateTime type because the core code is:
#[TentativeType]
public function setTime(
#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $hour,
#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $minute,
#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $second = 0,
#[PhpStormStubsElementAvailable(from: '7.1')] #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $microsecond = 0
): DateTime {}
But AFAIK the setTime() function doesn't actually return anything.
Adding : DateTime to AcmeDate::setTime() yields a Fatal Error:
public function setTime($hours, $minutes, $seconds = 0, $microseconds = 0):DateTime {
parent::setTime ( $hours, $minutes, $seconds, $microseconds );
}
Fatal error: Uncaught TypeError: AcmeDate::setTime(): Return value must be of type DateTime, none returned in /home/Acme/AcmeDate.php:116
Using null as a return type also throws an error saying it can't be standalone:
Fatal error: Null can not be used as a standalone type in ...
Using never throws a different error about implicit returns which I don't understand:
AcmeDate::setTime(): never-returning function must not implicitly return in...
I'm at a loss at this point. I'm sure it's something simple.
Solution 1:[1]
Since PHP 8.1, if the parent method explicitly specifies the return type, then the new method must also explicitly specify the type (https://php.watch/versions/8.1/internal-method-return-types - "lack of a return type declaration is also considered a return type mismatch"). As of PHP 9.0 this will be considered a bug. The DateTime::setTime class method has an empty body because it is only a definition and its C++ implementation is called instead: https://github.com/php/php-src/blob/master/ext/date/php_date.c
The error "Return value must be of type DateTime, none returned in /home/Acme/AcmeDate.php" occurs because your method does not return anything and there is a strict check in the php configuration, on my version no error occurs, but without specifying return method will return null (https://www.php.net/manual/en/functions.returning-values.php).
If you still need to change the return type in the overridden method (or not specify it), then you can add the #[\ReturnTypeWillChange] attribute.
So either of these two options will work:
First:
public function setTime($hours, $minutes, $seconds = 0, $microseconds = 0):DateTime {
return parent::setTime ( $hours, $minutes, $seconds, $microseconds );
}
Second:
#[\ReturnTypeWillChange]
public function setTime($hours, $minutes, $seconds = 0, $microseconds = 0) {
return parent::setTime ( $hours, $minutes, $seconds, $microseconds );
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
