Question

Okay. Now I give up. I have been playing with this for hours.

  • I have a variable name $data.
  • The variable contains these contents: (extracted by using var_export())

    array (
      'headers' =>
      array (
        'content-type' => 'multipart/alternative; boundary="_689e1a7d-7a0a-442a-bd6c-a1fb1dc2993e_"',
      ),
      'ctype_parameters' => 
      array (
        'boundary' => '_689e1a7d-7a0a-442a-bd6c-a1fb1dc2993e_',
      ),
      'parts' => 
      array (
        0 => 
        stdClass::__set_state(array(
          'headers' => 
          array (
            'content-type' => 'text/plain; charset="iso-8859-1"',
            'content-transfer-encoding' => 'quoted-printable',
          ),
          'ctype_primary' => 'text',
        )),
      ),
    )
    

    I removed some non-essential data.

  • I want to access the headers value (on the second line above) - simple: $data->headers
  • I want to access the headers value (on the fourteenth line after the stdClass:: stuff) - how?

How can I possibly access the values within the stdClass::__set_state section?

I tried var_export($data->parts); but all I get is

NULL

Was it helpful?

Solution

Is this variable declared the way you posted it? Like:

$data = array(
          'headers' =>
             array (
             …

In that case, I'm not quite sure how you can access 'headers' via $data->headers. It should be $data['headers'], because it is an array, not an object.

Further down, stdClass::__set_state(array('headers' => …)) statically calls the method __set_state of the class stdClass. Whatever this method does I don't know, but only its return value will be assigned to the 'parts' => array(0 => ...) key.

If OTOH what you're showing is the result of var_dump($data), then this is incorrect nonsense, since stdClass::__set_state() would never show up in a var_dump. Something is fishy either in your code or in what you posted and it's hard to say without seeing more of it.

Disregard the above, var_export prints classes this funky way.

$data['headers'] should do it for the first headers part. Further down, $data['parts'][0]->headers should do the trick.

OTHER TIPS

I ran into a similar problem with the open-source mail server Postal. In this case, I used the API to send an email message with two recipients. The API returns JSON, which I want to process to get the message ID Postal has assigned to each message. The JSON string decodes to a series of nested objects, according to print_r.

pObj: stdClass Object
(
    [status] => success
    [time] => 0.28
    [flags] => stdClass Object
        (
        )

    [data] => stdClass Object
        (
            [message_id] => a122e786-6c32-4085-b1ed-023e5923ca38@rp.postal.domain.com
            [messages] => stdClass Object
                (
                    [name1@domain1.com] => stdClass Object
                        (
                            [id] => 180
                            [token] => AblVpj6UW2wh
                        )

                    [name2@domain2.com] => stdClass Object
                        (
                            [id] => 181
                            [token] => io5wgEXO1boH
                        )

                )

        )

)

Looking at the structure, the first few layers are easy to extract. The trouble is that the messages object has attributes named for each recipient email address. Without knowing these address values a priori, I couldn't access the individual recipient objects programmatically to get at the message id.

I also examined this object using var_dump() and var_export(). That's where I saw this strange and misleading syntax: "stdClass::__set_state(array(". But there are no arrays at all in this object. In reality, this structure contains nothing but nested objects and attributes.

This situation was giving me fits until I asked the right question: what are the names of an object's attributes?

Now the programmatic solution is relatively easy because PHP has a function for that. I used get_object_vars() to get an array of attributes in the messages object. By simply looping on that array, I could then access the id and token attributes of each address. Here's the code, with a sample JSON response from Postal.

define('_EOL', "\n");
$json='{"status":"success","time":0.28,"flags":{},"data":{"message_id":"a122e786-6c32-4085-b1ed-023e5923ca38@rp.postal.domain.com","messages":{"name1@domain1.com":{"id":180,"token":"AblVpj6UW2wh"},"name2@domain2.com":{"id":181,"token":"io5wgEXO1boH"}}}}';

$pObj=json_decode($json);
$str='<pre>pObj: '.print_r($pObj, true)._EOL._EOL;
$str.=' - status='.$pObj->status._EOL;
$msgVars=get_object_vars($pObj->data->messages);
foreach ($msgVars as $varKey=>$msgObj)
{
    $str.=' - '.$varKey.':'._EOL;
    $str.='   - id='.$msgObj->id._EOL;
    $str.='   - token='.$msgObj->token._EOL;
}
echo($str.'</pre>');

What made this hard is that the Postal design uses variable attribute names in the messages object. I would have made messages an array and put the email address into an attribute named address along with the attributes id and token. But it is what it is, and I hope this helps someone else.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top