Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting an array to an object allows invalid property names?

Tags:

oop

php

I may have just ran into one of those "wtf PHP?" moments.

According to the PHP documentation [Class member variables] are defined by using one of the keywords public, protected, or private, followed by a normal variable declaration.

I would assume this means that properties must adhere to the same naming conventions as variables. Namely, it must not start with an integer. The following code, does indeed cause a parse error:

class Foo {
    public $1st_property;
}

The documentation also states when casting arrays to an object: Arrays convert to an object with properties named by keys, and corresponding values.

So I tried

$a['1st_key'] = "Hello, World!";
$o = (object)$a;

print_r($o);

And 1st_key is indeed a property

stdClass Object
(
    [1st_key] => Hello, World!
)

Point being: The property name begins with a number, which is not a valid variable name (of course, we can access that property with $o->{'1st_key'}). But, howcome when an array is cast to an object, invalid variable names can become property names?

like image 753
v0idless Avatar asked Nov 08 '11 15:11

v0idless


2 Answers

That's done by the cast. And technically spoken, those names are not invalid.

You need to differ how you can write (define) these names. If you write:

$1

That's an invalid label. But if you write

${1}

That label is not invalid.

This question might be interesting for you as well: Array to Object and Object to Array in PHP - interesting behaviour.

like image 146
hakre Avatar answered Nov 05 '22 11:11

hakre


You are right - there is no possibility to create an invalid property like:

class Foo {
    public $1st_property;
}

But you can do:

class Foo {
    function __construct() {
        $this->{'1st_property'} = 'default value';
    }

    function get1st_property() {
        return $this->{'1st_property'};
    }

    function set1st_property($value) {
        $this->{'1st_property'} = $value;
    }
}
like image 1
hsz Avatar answered Nov 05 '22 09:11

hsz