Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
220 views
in Technique[技术] by (71.8m points)

php - Is it possible to type hint more than one type?

Can I allow two different types using type hinting?

E.g. parameter $requester could be either of User or File:

function log (User|File $requester) {

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 { /** **/ }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...