PHP Type hinting to allow Array or ArrayAccess

僤鯓⒐⒋嵵緔 提交于 2019-12-30 06:11:33

问题


Is it possible to allow an Array or an object that implements ArrayAccess?

For example:

class Config implements ArrayAccess {
    ...
}

class I_Use_A_Config
{
    public function __construct(Array $test)
    ...
}

I want to be able to pass in either an Array or ArrayAccess.

Is there a clean way to do this other than manually checking the parameter type?


回答1:


No, there is no "clean" way of doing it.

The array type is a primitive type. Objects that implement the ArrayAccess interface are based on classes, also known as a composite type. There is no type-hint that encompasses both.

Since you are using the ArrayAccess as an array you could just cast it. For example:

$config = new Config;
$lol = new I_Use_A_Config( (array) $config);

If that is not an option (you want to use the Config object as it is) then just remove the type-hint and check that it is either an array or an ArrayAccess. I know you wanted to avoid that but it is not a big deal. It is just a few lines and, when all is said and done, inconsequential.




回答2:


They have a real solution in PHP 7.1.

http://php.net/manual/en/migration71.new-features.php#migration71.new-features.iterable-pseudo-type

The iterable pseudo-type is what you want. Any array or Traversable type, (which is the base interface for Iterators) will pass this check.

Now, to make this clear for anyone who wants to get super in-depth, yes, there are going to be edge cases. You should be thinking of these edge cases and resolving them yourself, but if you want to make sure that if someone passes in a traversable element that cannot be accessed via a key, you can do this.

http://php.net/manual/en/function.iterator-to-array.php

Now regardless of what they pass in the type-hint, you will have an array, but this can remove the benefits of using a Generator for memory reduction. It should be obvious, but apparently it isn't, so here it is. You, the programmer, are responsible for figuring out your particular use cases for code and how you are planning on using it and what the appropriate use case is for the code.

Since this still isn't clear enough, let's say you are trying to pass in something that is type-hintable and expecting a particular method or variable to exist, then you are doing bad programming. You should be implementing a contract that has the return type you are looking for and pass that in rather than a generic type. If you only want to do something generic like looping, that's what iterable types are for. The hint is in the name: Iterate.



来源:https://stackoverflow.com/questions/14806696/php-type-hinting-to-allow-array-or-arrayaccess

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!