Bug #68654 [Opn->Nab]: empty function: late evaluation of argument
| From: | requinix@php.net | 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