4

When you implement the _toString method on a class, you are able to convert the object in string

$string =(string) $object

Is there an equivalent for converting in array

$array=(array) $object

From what I have tested, with this code, the attributes of the objet are transformed in index of the array, even if this object implement ArrayAccess.

I expected that casting an object with array access, I would obtain an array thith the same values I could access with the object

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'));

I also Notice that the native ArrayObject class has a the behavior I expected

2
  • Either derive from ArrayObject and reuse getArrayCopy; or reimplement it by just returning the $values prop. Casting won't work, as there's no __toArray handling. Commented Dec 2, 2014 at 9:39
  • public function MyObject implements ArrayAccess{ <-- this is not valid PHP syntax. You want class MyObject implements ArrayAccess { .... Commented Aug 22, 2017 at 21:13

3 Answers 3

4

No, there is no magic function to cast object as array.

ArrayObject is implemented with C and has weird specific behaviors.

Implement custom method asArray and use it.

Sign up to request clarification or add additional context in comments.

1 Comment

A vague response, offering no resolution.
1

Actually, it's impossible to write a general function:

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

Why? Because ArrayAccess interface just gives a way to use $aa[/*argument*/] syntax, but does not give a way to iterate over all possible arguments.

We used to think that array has a finite number of keys. However ArrayAccess let us create objects having an infinite set of keys (note, the same concerns Traversable: i.e. prime numbers are "traversable").

For example, one can write a class, implementing ArrayAccess, that acts like a HTTP client with a cache (I'm not saying that it's a good idea; it's just an example). Then offsetExists($url) tells if a URL gives 200 or not, offsetGet($url) returns a content of a URL, offsetUnset($url) clears cached content, offsetSet throws a LogicException, 'cause setting a value makes no sense in this context.

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

Or maybe one wants to read/write/unset (delete) files with ArrayAccess.

Or maybe something like (set of even numbers is infinite):

$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 objects from academic examples above cannot be converted into finite arrays.

Comments

1

You can use json_decode and json_encode to get the most generic function for it:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.