php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #43936 __empty() magic method
Submitted: 2008-01-25 14:40 UTC Modified: 2016-03-20 17:36 UTC
Votes:23
Avg. Score:4.6 ± 1.0
Reproduced:21 of 22 (95.5%)
Same Version:6 (28.6%)
Same OS:13 (61.9%)
From: james dot laver at gmail dot com Assigned:
Status: Wont fix Package: Class/Object related
PHP Version: 5.2.5 OS: GNU/Linux
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2008-01-25 14:40 UTC] james dot laver at gmail dot com
Description:
------------
Using empty() on a variable that would be pulled from __get does not work, this has been established as 'not a bug' by more bug reports than anyone cares to remember, however, the documentation's suggestion of using __isset is not adequate if you wish to implement both isset and empty functionality.

Thus I propose an __empty() magic method which would overload empty() in the way that __isset() overrides isset().

Reproduce code:
---------------
public function __empty($value)
{
  return empty($this->_values[$value]);
}

Expected result:
----------------
empty($object->my_empty_value) = true

Actual result:
--------------
.....

Patches

__empty.txt (last revision 2011-08-24 00:43 UTC) by chrisstocktonaz at gmail dot com)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-06-30 11:51 UTC] pajoye@php.net
-Status: Open +Status: Assigned -Package: Feature/Change Request +Package: *General Issues -Assigned To: +Assigned To: dmitry
 [2010-06-30 11:51 UTC] pajoye@php.net
hi Dmitry,

What's your thoughts on this one? Someone asked me about it and we found this old bug.

A workaround is to implement __isset but that makes little sense (isset != empty) and is counter intuitive.
 [2010-06-30 11:52 UTC] pajoye@php.net
-Package: *General Issues +Package: Class/Object related
 [2010-06-30 12:00 UTC] icy at lighttpd dot net
Simple test script to trigger the bug:

<?php

class Foo {
	public $vars;

	function Foo() {
		$this->vars['bar'] = 1;
	}

	function __get($var) {
		return $this->vars[$var];
	}
}

$foo = new Foo;

var_dump(empty($foo->bar));
$baz = $foo->bar;
var_dump(empty($baz));

Expected result:
----------------
bool(false) bool(false) 

Actual result:
--------------
bool(true) bool(false)
 [2010-06-30 13:02 UTC] pajoye@php.net
-Type: Feature/Change Request +Type: Documentation Problem -Assigned To: dmitry +Assigned To: pajoye
 [2010-06-30 13:02 UTC] pajoye@php.net
Let document the __isset requirements better, when one relies on empty.
 [2010-10-22 15:50 UTC] kalle@php.net
-Status: Assigned +Status: Open -Package: Class/Object related +Package: Documentation problem -Assigned To: pajoye +Assigned To:
 [2010-10-23 16:06 UTC] kalle@php.net
Automatic comment from SVN on behalf of kalle
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=304662
Log: Added a remark about overloaded properties and language constructs (Bug #43936)
 [2010-10-23 16:08 UTC] kalle@php.net
-Type: Documentation Problem +Type: Feature/Change Request -Package: Documentation problem +Package: Class/Object related
 [2010-10-23 16:08 UTC] kalle@php.net
Fixed the overloading property vs language construct issue in the documentation.

This feature request is still valid, so moving it to be one instead of a documentation issue
 [2011-08-24 00:40 UTC] chrisstocktonaz at gmail dot com
I made the start of a patch for this, but there is some issues that would need to 
be worked out with has_property calls, it seems oddly interfaced with by the 
various callers.

http://pastebin.com/d5gQycDB
 [2012-07-20 13:44 UTC] thomas at sibben dot nl
The documentation states:

"empty() only checks variables as anything else will result in a parse error"

if 'everything else' is a __get() returning an array with a value in it, it returns TRUE,

Ubuntu 10.04 PHP 5.3.2-1ubuntu4.17
 [2012-07-20 13:53 UTC] thomas at sibben dot nl
reproducable with:

class Test {
        private $test;
 
        function __construct($test)
        {
                $this->test = $test;
        }
 
        public function __get($key)
        {
                return $this->$key;
        }
 
        public function getTest()
        {
                return $this->test;
        }
}
 
$test = new Test('test');
 
if (!empty($test->test)) {
        echo $test->test;
} else {
        echo 'empty';
}
 
echo '<br />';
echo $test->test;
echo '<br />';
echo $test->getTest();
 [2016-03-20 17:36 UTC] nikic@php.net
-Status: Open +Status: Wont fix
 [2016-03-20 17:36 UTC] nikic@php.net
This functionality is already supported, you simply need to implement both __isset() and __get(). empty($foo->bar) is semantically identical to !isset($foo->bar) || !$foo->bar. As such, a meaningful handling of empty() requires both of these handlers to be implemented.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC