Bug #68654 [Opn->Nab]: empty function: late evaluation of argument

From: Date: Fri, 26 Dec 2014 05:20:38 +0000
Subject: Bug #68654 [Opn->Nab]: empty function: late evaluation of argument
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-189209@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=68654&edit=1 ID: 68654 Updated by: requinix@php.net Reported by: your dot brother dot t at hotmail dot com Summary: empty function: late evaluation of argument -Status: Open +Status: Not a bug Type: Bug Package: Scripting Engine problem Operating System: Windows 8.1 64-bit PHP Version: 5.6.4 Block user comment: N Private report: N New Comment: Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://www.php.net/manual/ and the instructions on how to report a bug at http://bugs.php.net/how-to-report.php Your repro script is no good. I'm going to assume you meant more like http://3v4l.org/u1jQt For isset() and empty() to work properly on objects that implement __get, __isset also needs to be implemented. Those functions will not try to access a value until they know it exists, and without __isset to tell them otherwise they will look for actual accessible properties. > var_dump(empty($glass->liquid)); empty because ->liquid is not accessible. > var_dump(empty($glass->liquid->apple)); empty because ->liquid is not accessible. > var_dump(empty(($glass->liquid->apple))); This one is a bit trickier to answer. Either it's empty because ->liquid is still not accessible, which is likely the logic used by HHVM and the last couple months' worth of PHP 7, or it is not empty because the extra parentheses forced evaluation and the subsequent value is not empty. Regardless, you need to implement __isset. See http://3v4l.org/qaeJL which gives the expected false/false/false. You can put logging statements in __get and __isset to see exactly what is happening. Previous Comments: ------------------------------------------------------------------------ [2014-12-25 21:59:15] your dot brother dot t at hotmail dot com Description: ------------ --- From manual page: http://www.php.net/function.empty --- 5.5.0 empty() now supports expressions, rather than only variables. --- The empty() can't evaluate multiple __get() results explicitly. It seems that instead of correct nesting which is left to right nesting: empty(...(((($this)->a)->b)->c)->...) It uses a right to left nesting: empty(($this->(a->(b->(c)->...)))...) Which returns null at the first left-most -> operator, yielding to an empty call to become true. Test script: --------------- <?php class Juice extends Liquid{ protected $apple; protected $orange; public function __get($name) { return $this->$name; } public function __construct($apple, $orange) { $this->apple = $apple; $this->orange = $orange; } } class Glass { protected $liquid; public function __get($name) { return $name == "liquid" ? $this->liquid : false; } public function __construct() { $this->juice = new Juice(3, 5); } } $glass = new Glass(); var_dump(empty($this->liquid)); var_dump(empty($this->liquid->apple)); var_dump(empty(($this->liquid->apple))); ?> Expected result: ---------------- bool(false) bool(false) bool(false) Actual result: -------------- bool(false) bool(true) bool(false) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=68654&edit=1

« previous php.bugs (#189209) next »