php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #52807 magic __toArray() for objects
Submitted: 2010-09-09 22:33 UTC Modified: 2020-04-08 10:52 UTC
Votes:24
Avg. Score:4.6 ± 0.9
Reproduced:21 of 21 (100.0%)
Same Version:13 (61.9%)
Same OS:11 (52.4%)
From: jtegwen at gmail dot com Assigned:
Status: Suspended Package: Class/Object related
PHP Version: Irrelevant OS: n/a
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2010-09-09 22:33 UTC] jtegwen at gmail dot com
Description:
------------
It would be nice to have an analogous method to __toString() for arrays.. maybe __toArray() for customized array return. 

Test script:
---------------
class myObject {
  private $data1;
  private $data2;
  private $meta1;

  public function __construct($data1, $data2) {
    $this->data1 = $data1;
    $this->data2 = $data2;
    $this->meta1 = strlen($data1) + strlen($data2);
  }
  public function __toArray() {
    return array('data1'=>$this->data1, 'data2'=>$this->data2);
  }
}

  $obj = new myObject('test', 'script');
  var_dump($obj);



Expected result:
----------------
array('data1'=>'test', 'data2'=> 'script')

Actual result:
--------------
Not implemented

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-09-10 04:58 UTC] aharvey@php.net
-Status: Open +Status: Duplicate
 [2010-09-10 04:58 UTC] aharvey@php.net
Probably better bundled under request #52583 -- the RFC linked to there is specifically to deal with casting to scalar types, but the syntax suggested in the feature request is general enough to deal with arrays.
 [2010-09-10 17:21 UTC] jtegwen at gmail dot com
I found that request when researching this one. I read that as casting *to* an object not casting *from* an object. 

Am I missing something?
 [2010-09-12 04:06 UTC] aharvey@php.net
-Status: Duplicate +Status: Open
 [2010-09-12 04:06 UTC] aharvey@php.net
You are quite correct about request #52583. My apologies. I
remember skimming it when it came in, but obviously not very well. :)

To be honest, I think this is a better candidate for a thread on the
Internals mailing list or an RFC than a feature request here. I also
think this is extremely unlikely to make it in in any case,
particularly without a patch.

Nevertheless, I'll reopen this for now.
 [2010-10-03 18:36 UTC] + at ni-po dot com
@aharvey: Couldn't the patch in the RFC you mentioned be modified to support arrays, too? Or would the implementation for arrays be completely different to the one for arrays?
 [2010-10-11 17:17 UTC] dmgx dot michael at gmail dot com
I've found that when I have an object I need to behave like an array in some contexts that it is worth the time to implement Iterator and Array in the object, which allows the object to behave like an array.  It takes more effort than implementing a theoretical magic __toArray() method, but its worth it. 

Read here for information on doing this: http://php.net/manual/en/language.oop5.iterations.php
 [2012-09-24 12:50 UTC] umpirsky at gmail dot com
@dmgx This is not the problem the bug is about. What if you have some library 
which casts variables to arrays, like Zend_XMLRPC for example. Iterator or 
ArrayAccess will not do the job, since you need control over casting your class to 
array.
 [2015-01-15 09:18 UTC] bpolaszek at gmail dot com
I really think this is relevant.
PHP 5.4 introduced something similar with the JsonSerializable interface.
When you call json_encode on an object that implements it, it automatically calls the jsonSerialize() method that returns a string, an array, an integer, a float or a boolean.

When you implement the jsonSerialize() method, you generally want to have a json-friendly representation of your current object, and you normally return an associative array with the properties you want to output. That looks like a __toArray() method, doesn't it ?

What would be very nice is the following code to work :
class A {

    protected   $property1 = 'foo', 
                $property2 = ['foo', 'bar'], 
                $property3;

    public function __toArray() {
        return [
            'property1' =>  $this->property1,
            'property2' =>  $this->property2,
        ];
    }

}

class B {
    public static function doSomethingWithData(array $data) {
        // ...
    }
}

$a  =   new A;
B::doSomethingWithData((array) $a);
array_change_key_case($a, CASE_UPPER); // Would automatically cast $a to array and output ['PROPERTY1' => 'foo, 'PROPERTY2' => ['foo', 'bar']]
 [2016-06-16 20:27 UTC] igorsantos07 at gmail dot com
Something that should be pointed out in the issue is that (array)$object is one of the most common object casts used out there. String casting are useful in templating, while array casting is useful for API returns, for instance... And there's currently no way to instinctively do this call in a protective way, as we can do with (string)$object.

Calling $object->toArray() is bulky and unreliable: if the developer knows the object will have that method (so they can call it), he already knows it needs further processing, just like string casts do.
Furthermore, implicit casts are always unreliable without a __toArray() magic method.

As an API developer for a couple of years, I've stumbled upon this API discrepancy between magic __toString() and explicit toArray() implementations. That's quite a bad smell for PHP's OO system.

It seems there's already an RFC with a patch to discuss that. How's this going?
https://wiki.php.net/rfc/object_cast_to_types
 [2016-07-11 20:48 UTC] geiger at karim dot email
Hi there,

sorry for warming this up one more time, but I think __toArray() isn't the perfect solution to the problem. Since PHP is already able to use an object as an array using the Iterator interface, why don't we just extend this?

I made my thoughts a bit clearer in request #72579, if anyone is interested.
 [2017-04-05 14:45 UTC] rulatir at wp dot pl
Because e.g. array_chunk() won't accept an object even if it meticulously implements all the gazillion iteration and array access interfaces.
 [2019-10-29 12:46 UTC] php at shark dot kom dot cz
A lot of functions depends on pure arrays even if any collection will be good enough.

So I suggest that object implementing __toArray() magic method will be casted using this method.
 [2020-04-08 10:52 UTC] cmb@php.net
-Status: Open +Status: Suspended
 [2020-04-08 10:52 UTC] cmb@php.net
There is already a respective RFC[1] (currently under discussion),
so I'm suspending this ticket for the time being.

[1] <https://wiki.php.net/rfc/to-array>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 05:01:29 2024 UTC