I'm summarising a few points on empty() with inaccessible properties, in the hope of saving others a bit of time. Using PHP 5.3.2.
<?php
class MyClass {
private $foo = 'foo';
}
$myClass = new MyClass;
echo $myClass->foo;
?>
As expected, this gives "Fatal error: Cannot access private property MyClass::$foo".
But substitute the line
if (empty($myClass->foo)) echo 'foo is empty'; else echo 'foo is not empty';
and we get the misleading result "foo is empty".
There is NO ERROR OR WARNING, so this is a real gotcha. Your code will just go wrong silently, and I would say it amounts to a bug.
If you add two magic functions to the class:
public function __get($var) { return $this->$var; }
public function __isset($var) { return isset($this->$var); }
then we get the expected result. You need both functions.
For empty($myClass->foo), I believe PHP calls __isset, and if that is true returns the result of empty on the result of __get. (Some earlier posts wrongly suggest PHP just returns the negation of __isset).
BUT …
See the earlier post by php at lanar dot com. I confirm those results, and if you extend the test with isset($x->a->b->c) it appears that __isset is only called for the last property in the chain. Arguably another bug. empty() behaves in the same way. So things are not as clear as we might hope.
See also the note on empty() at
http://uk3.php.net/manual/en/language.oop5.overloading.php
Clear as mud!