As of PHP 8.0, this will be possible with the inclusion of Union Types.
The proposal has been voted 61 in favour to 5 against, and the implementation is ready to go.
There was a previous RFC proposing this, mentioned in another answer, but that one ended up being rejected.
It will work exactly as the example in your question:
class F
{
public function foo (File|Resource $f) : int|float { /** implement this**// }
}
Which means that F::foo()
expects either a File
or a resource, and will return an int
or a float
.
A couple additional points:
Nullability
Additionally, you can declare an union with null
. A|null
is equivalent to ?A
, but a more complex declaration as A|B|null
is also possible.
"False" pseudo-type
It's also possible use the false
type as part of a union-type declaration. E.g. int|false
. This is included mostly because of historical reasons, since some internal functions return false
on some types of error conditions. See strpos() as an example.
More modern functions should probably return null
or throw an exception in these situations, but this alternative is included to account for legacy code.
Adding and removing part of a union type on inheritance
It is legal to add union types for parameter type hints (thus, making the function less restrictive), and to remove union types for return type hints (making the return type more specific).
Given the class F
from above, this is legal:
class G extends F
{
public function foo(File|Resource|string $f) : int { /** **/ }
}
But this is not:
class H extends F
{
public function foo(File $f) : int|float|bool { /** **/ }
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…