Self-Generating Class Objetcs in PHP

I have a directory on the webserver in my development environment where I do little experiments. I try out stuff that I cant figure out by looking into the PHP documentation – either because I can’t find the right place to look or because it’s just not explained.

Sadly I need to use that directory quite often. Almost daily.

Today I found this little gem:

$x->y->z = 123;
echo $x->y->z;

Without trying, what would you guess what happens when I try to set a value to a property of a property of a variable that I never initialized with an object?

I thought, this would fail and quit with some kind of error message. But no: This script prints „123“.

When I add a print_r($x) to my code I get this:

stdClass Object
(
    [y] => stdClass Object
        (
            [z] => 123
        )

)

That means that PHP creates an object for me when I try to access properties of a variable that is not set, yet.

So: What happens when the variable HAS a value before I try to set a property?
I have to answer with „Well, that depends…“

  • If the variable is NULL or an empty string (!), an object will be auto-generated
  • If the variable is numeric (including „0“ (!)) or a string with a length of at least 1 character nothing happens at all. No error message, nothing.
  • If the variable already is an object, nothing needs to be done. But note that if the object has no property of the given name, a property is added automatically

I find it quite strange that an empty string seems to be handled the same way as NULL while the numeric value 0 is not.

Another magic behavior uncovered… Let’s see what comes next…

Eine Antwort auf „Self-Generating Class Objetcs in PHP“

  1. While that is true, do note that when the E_STRICT error level is set (which I *always* have set during development or testing) it returns a „Strict notice: creating standard object from empty value.“

    Something like this (untested) would solve that issue:

    class standardClass extends stdClass
    {
    
    	public function __get( $index )
    	{
    	
    		if( !isset( $this->$index ) || !$this->$index instanceof stdClass )
    		{
    			$this->$index = new standardClass();
    			return $this->$index;
    		}
    		else
    		{
    			return $this->$index;
    		}
    		
    	}
    	
    }
    
    $x = new standardClass();
    $x->y->z = 123;
    print_r( $x );
    

    If the above code is unreadable, check pastebin: http://pastebin.com/PcfGakyM

Kommentare sind geschlossen.