是否可以允许Array或实现ArrayAccess的对象?
例如:
class Config implements ArrayAccess {
...
}
class I_Use_A_Config
{
public function __construct(Array $test)
...
}
我希望能够传入Array或ArrayAccess。
除了手动检查参数类型外,还有一种干净的方法吗?
答案 0 :(得分:13)
不,没有“干净”的方式。
array
类型是基元类型。实现ArrayAccess
接口的对象基于类,也称为复合类型。没有包含两者的类型提示。
由于您使用ArrayAccess
作为数组,因此您可以将其强制转换。例如:
$config = new Config;
$lol = new I_Use_A_Config( (array) $config);
如果这不是一个选项(您希望按原样使用Config
对象),则只需删除类型提示并检查它是数组还是ArrayAccess
。我知道你想避免这种情况,但这不是什么大问题。这只是几行而且,当所有这些都说完了,无关紧要。
答案 1 :(得分:1)
PHP 8.0+
您可以使用 array
和 ArrayAccess
的并集。
class I_Use_A_Config
{
public function __construct(array|ArrayAccess $test)
...
}
答案 2 :(得分:-2)
他们在PHP 7.1中有一个真正的解决方案。
http://php.net/manual/en/migration71.new-features.php#migration71.new-features.iterable-pseudo-type
可迭代的伪类型就是你想要的。任何数组或Traversable类型(迭代器的基本接口)都将通过此检查。
现在,为了让任何想要超级深入的人明白这一点,是的,会有边缘情况。你应该考虑这些边缘情况并自己解决它们,但如果你想确保如果有人传入一个无法通过密钥访问的可遍历元素,你可以这样做。
http://php.net/manual/en/function.iterator-to-array.php
现在无论它们在类型提示中传递了什么,你都会有一个数组,但这可以消除使用Generator减少内存的好处。这应该是显而易见的,但显然它不是,所以现在就是这样。作为程序员,您负责确定代码的特定用例以及计划如何使用代码以及代码的适当用例。
由于这还不够清楚,让我们说你试图传递一些类型可以阻止的东西,并期望存在一个特定的方法或变量,那么你就是在做错编程。您应该实现一个具有您正在寻找的返回类型的契约,并将其传递给而不是泛型类型。如果你只想做一些通用的事情,比如循环,那就是可迭代类型的用途。提示名称为:Iterate。
答案 3 :(得分:-4)
好的php支持Array / Object的类型提示。所以Array应该可以正常工作。但是,在仅允许Array类型的方法上传递ArrayAccess对象可能会抛出错误。 ArrayAccess主要用于迭代ArrayAccess对象,就像在foreach中使用数组一样。