PHP empty() on __get accessor

oop, php

Solution

Based on a reading of the `empty`'s manual page and comments (Ctrl-F for isset and/or double underscores), it looks like this is known behavior, and if you want your `__set` and `__get` methods and `empty` to play nice together, there's an implicit assumption that you implement a `__isset` magic method as well.

It is a little bit unintuitive and confusing, but that tends to happen with most meta-programming, particularly in a system like PHP.

Problem

Using PHP 5.3 I'm experiencing weird / non-intuitive behavior when applying `empty()` to dynamic object properties fetched via the `__get()` overload function. Consider the following code snippet: ``` <?php class Test { protected $_data= array( 'id'=> 23, 'name'=> 'my string' ); function __get($k) { return $this->_data[$k]; } } $test= new Test(); var_dump("Accessing directly:"); var_dump($test->name); var_dump($test->id); var_dump(empty($test->name)); var_dump(empty($test->id)); var_dump("Accessing after variable assignment:"); $name= $test->name; $id= $test->id; var_dump($name); var_dump($id); var_dump(empty($name)); var_dump(empty($id)); ?> ``` The output of this function is as follow. Compare the results of the `empty()` checks on the first and second result sets: Set #1, unexpected result: ``` string(19) "Accessing directly:" string(9) "my string" int(23) bool(true) bool(true) ``` Expecting Set #1 to return the same as Set #2: ``` string(36) "Accessing after variable assignment:" string(9) "my string" int(23) bool(false) bool(false) ``` This is really baffling and non-intuitive. The object properties output non-empty strings but `empty()` considers them to be empty strings. What's going on here?

Original source