php转换在数组中实现ArrayAccess的对象

时间:2014-12-02 09:36:02

标签: php casting type-conversion arrayaccess

在类上实现_toString方法时,可以转换字符串

中的对象
$string =(string) $object

是否有等效的数组转换

$array=(array) $object

根据我的测试,使用此代码,objet的属性将在数组的索引中进行转换,即使此对象实现了ArrayAccess。

我期望使用数组访问来转换对象,我会获得一个与我可以使用对象访问的值相同的数组

public function MyObject implements ArrayAccess{
     private $values;
     public function __construct(array $values){
        $this->values=$values;
     }
     public function offsetSet($name,$value){
        $this->values[$name]=$value;
     }
     //etc...
}

$myObject=new MyObject(array('foo'=>'bar');

$asArray=(array)$myObject;

print_r($asArray);
// expect array('foo'=>'bar')
// but get array('MyObjectvalues'=>array('foo'=>'bar'));

我还注意到本机ArrayObject类具有我期望的行为

3 个答案:

答案 0 :(得分:0)

不,没有magic function将对象转换为数组。

ArrayObject是用C实现的,具有奇怪的特定行为。

实施自定义方法asArray并使用它。

答案 1 :(得分:0)

实际上,编写一般功能不可能

/*
 * @return array ArrayAccess object converted into an array
 */
function (ArrayAccess $arrayAccessObject): array { /* ... */ }

为什么?因为ArrayAccess接口仅提供了一种使用$aa[/*argument*/]语法的方法,却没有提供对所有可能参数进行迭代的方法。

我们以前认为array的键数量有限。但是,ArrayAccess让我们创建具有无限键集的对象(请注意,Traversable也存在相同的问题:即素数是“可遍历的”)。

例如,可以编写一个实现ArrayAccess的类,该类的行为类似于具有缓存的HTTP客户端(我并不是说这是一个好主意;这只是一个示例)。然后offsetExists($url)判断URL是否给出200,offsetGet($url)返回URL的内容,offsetUnset($url)清除缓存的内容,offsetSet抛出LogicException,'因为在这种情况下设置值没有意义。

// ...
if (empty($client['https://example.com/file.csv'])) {
    throw new RuntimeException('Cannot download the file');
}
$content = $client['https://example.com/file.csv'];
// ...

或者也许有人想使用ArrayAccess来读取/写入/取消设置(删除)文件。

或者类似(偶数集是无限的)之类的东西:

$even = new EvenNumberChecker(); // EvenNumberChecker implements ArrayAccess
$even[2]; // true
$even[3]; // false
$even[5.6]; // throws UnexpectedValueException
isset($even[7.8]); // false
$even[0] = $value; // throws LogicException
上面学术示例中的

ArrayAccess对象不能转换为有限数组。

答案 2 :(得分:0)

使用PHP 7.4的spread operator数组解压缩,现在很容易将ArrayAccess对象转换为数组:

$array = [...$object];