php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73242 empty($obj->protectedPropery) does not __get the property value
Submitted: 2016-10-04 14:24 UTC Modified: 2016-10-04 14:53 UTC
From: touzfik10 at gmail dot com Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 7.0.11 OS: windows
Private report: No CVE-ID: None
 [2016-10-04 14:24 UTC] touzfik10 at gmail dot com
Description:
------------
I think empty($expression) is supposed to evaluate $expression before it checks if it is empty.

In the code bellow, empty($obj->protectedProperty) is supposed to call __get before checking if it's empty. That makes sense, right? Well, I don't think it's happening.

Sorry if I am missing something. But I think this behavior should change.

Test script:
---------------
$fooList = [
    new Foo,
    new Foo
];

$bar = new Bar($fooList);

var_dump(empty($bar->fooList)); // true

$fooList = $bar->fooList;
var_dump(empty($fooList)); // false

class Foo { }

class Bar
{
	protected $fooList = [];

	public function __construct(array $fooList)
	{
		$this->fooList = $fooList;
	}

	public function __get(string $property)
	{
		return $this->$property;
	}
}


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-10-04 14:53 UTC] requinix@php.net
-Status: Open +Status: Not a bug -Type: Feature/Change Request +Type: Bug
 [2016-10-04 14:53 UTC] requinix@php.net
empty will first confirm the existence of the variable, and the default behavior is to check whether the variable is actually defined (and accessible) on the object. That's not the case for yours so empty returns true.

To override that behavior you must implement __isset.
http://php.net/manual/en/language.oop5.overloading.php#object.isset

Before: https://3v4l.org/meEFH
After:  https://3v4l.org/1mYgv

You should consider doing __set too or else calling code could define variables on the object. It could just throw an exception to prevent setting values if you wanted.
Really, for nearly every class out there __get/set/isset should come as a package deal - all or none.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 06:01:30 2024 UTC