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

pkwftd7m  于 2023-01-08  发布在  PHP
关注(0)|答案(3)|浏览(74)

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

$string =(string) $object

是否有在数组中转换的等效项

$array=(array) $object

根据我的测试,使用此代码,对象的属性将转换为数组的索引,即使此对象实现了ArrayAccess。
我期望用数组访问来转换对象,我会得到一个数组,它的值与我用对象访问的值相同

public class 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类具有我所期望的行为

xqk2d5yq

xqk2d5yq1#

不,没有magic function可将对象转换为数组。
ArrayObject是用C实现的,并且具有奇怪的特定行为。
实现并使用自定义方法asArray

vmdwslir

vmdwslir2#

实际上,写一个通用函数是不可能的

/*
 * @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对象不能被转换成有限数组。

nwnhqdif

nwnhqdif3#

你可以使用json_decodejson_encode来获得最通用的函数:

public static function toArray(ArrayAccess $array): array
{
    return json_decode(
        json_encode($array),
        true
    );
}

相关问题