2

I am casting an object to array and after that I am unable to access the resulting array by a key.

This is the code

print_r($new);
$new = (array)$new;
echo $new['EPPContactemail'];

foreach($new as $attr=>$value)
{
    echo "$attr => $value \n";
}

And the output is

EPPContact Object
(
    [id:EPPContact:private] => 6553377C74FC9899
    [roid:EPPContact:private] => 50085436-UK
    [status:EPPContact:private] => ok
    [voice:EPPContact:private] => +44.554545454
    [email:EPPContact:private] => some@email.com
    [fax:EPPContact:private] => 
    [clID:EPPContact:private] => TSOHOST
    [crID:EPPContact:private] => EPP-TSOHOST
    [crDate:EPPContact:private] => 2013-07-17T09:53:41
)

Notice: Undefined index: EPPContactemail in /home/parvhraban/domains/src/local_libs/EPP/Builder/Contact/Update.php on line 9
EPPContactid => 6553377C74FC9899
EPPContactroid => 50085436-UK
EPPContactstatus => ok
EPPContactvoice => +44.554545454
EPPContactemail => some@email.com
EPPContactfax => 
EPPContactclID => TSOHOST
EPPContactcrID => EPP-TSOHOST
EPPContactcrDate => 2013-07-17T09:53:41

I can clearly see that EPPContactemail key exists and holds the value although when accessing it (line 3, echo statement) it throws an error of undefined index.

Could you please explain me what causes this behaviour?

000
  • 26,951
  • 10
  • 71
  • 101
Vladimir Hraban
  • 3,543
  • 4
  • 26
  • 46

1 Answers1

8

When casting an object to an array, certain properties (private, protected and parent properties) are assigned to the array, with keys that look like:

*protected
ClassNamePrivate
ParentNameProperty

But they really look like this:

"\0*\0protected"
"\0ClassName\0Private"
"\0ParentName\0Property"

That's what's causing your problems here.
Replace:

echo $new['EPPContactemail'];

with

echo $new["\0EPPContact\0email"];

And take it from there.
Note that you'll have to use double quotes as string delemiters, because '\0' !== "\0", just as '\n' !== "\n"

This behaviour is documented on php.net, though it's rather well hidden

NikiC
  • 100,734
  • 37
  • 191
  • 225
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • What the hell is a "binary string" ? oO – Virus721 Jul 17 '13 at 09:13
  • is the `b` there for a binary string really needed? you aren't dealing with any character with the most significant bit set?! _EDIT:_ Also array access for example is binary safe… so, is it needed or just for confusing readers? ;-) – bwoebi Jul 17 '13 at 09:16
  • Wow, fantastic, I was never aware of this quirk. Thanks for the link. – Vladimir Hraban Jul 17 '13 at 09:21
  • @EliasVanOotegem At least I just didn't need it: `class a { protected $var = 2; } $a = (array)new a; var_dump($a["\0*\0var"]);` gives `int(2)` as expected, without a `b` there. (with b it works too; but it isn't necessary.) – bwoebi Jul 17 '13 at 09:25
  • @EliasVanOotegem http://3v4l.org/oCIMK … seems you are doing something wrong... (utf-8 surely ;-)) – bwoebi Jul 17 '13 at 09:28
  • I can confirm it works for me without B on PHP 5.3.3 – Vladimir Hraban Jul 17 '13 at 09:33
  • 1
    @EliasVanOotegem Now I'd give an additional upvote if I'd be allowed to :-) But really. Everyone who uses another encoding than utf-8 in PHP should write ---hundred--- _thousand_ times: "I like failing when coding because I like using other charsets than UTF-8". – bwoebi Jul 17 '13 at 09:42
  • 1
    @EliasVanOotegem Sorry, I won't upvote not fully correct answers ;-) – bwoebi Jul 17 '13 at 10:20
  • @EliasVanOotegem Why did you delete your post in the other thread? Just remove the wrong information, verify my comment and write it in your words in the post - please. This question needs another answer than _it's best practice_ etc. Btw. to get information about the internals, first read a bit around in the bit documentation about it and http://www.phpinternalsbook.com (_not yet finished_). And then look at the source code (I'd use http://lxr.php.net/PHP_TRUNK to quickly get definitions of functions and symbols when finding unknown things) to get some deeper understanding of specific things. – bwoebi Jul 17 '13 at 12:17
  • 6
    Please remove the usages of `b` and `(binary)` from this answer. They are unnecessary and your explanations for their use are not correct. The `b` string prefix is simply ignored and `(binary)` is exactly equivalent to `(string)`. – NikiC Jul 18 '13 at 12:19