5

Can any one tell what does below given lines means?

The lines below are copied from PHP manual:

Note:

It is not possible to use overloaded properties in other language constructs than isset(). This means if empty() is called on an overloaded property, the overloaded method is not called.

To workaround that limitation, the overloaded property must be copied into a local variable in the scope and then be handed to empty().

BUT this is not true that we cant call empty() on overloaded properties, when i called empty() , it triggered __isset()

Poonam Bhatt
  • 10,154
  • 16
  • 53
  • 72

3 Answers3

5

It is a documentation bug:

<?php
class PropNameReturn {
    function __isset($propname){
          return true;

    }
    function __get($propname){
          echo 'Yes, it IS called!'.PHP_EOL;
          return $propname;
    }
}
$o = new PropNameReturn();
var_dump(empty($o->this_prop_name));
//Yes, it IS called!
//bool(false)
$b = new stdClass();
var_dump(empty($b->this_prop_name));
//bool(true)
Wrikken
  • 69,272
  • 8
  • 97
  • 136
  • that is what I have observed...and want suggestions from other php developers...thanks... – Poonam Bhatt Jun 16 '12 at 13:19
  • Yep, depends on the `__isset()`, see the different result in @Kaii's answer. – Wrikken Jun 16 '12 at 13:21
  • Depends on `__isset()` and the results of `__get()` .. if `__isset()` returns true but `__get()` returns empty output, then `empty($foo->bar)` evaluates true. See my edited answer. – Kaii Jun 16 '12 at 13:33
4

Looks like the manual is wrong. This also works in PHP 5.2

By the way it seems that __get() is called when used by empty(), but the result also depends on __isset().

empty() returns true only if __isset() returns true and __get() returns an empty value.

See this example code:

class Foo {
    function __get($name) {
        if ($name == "bar")
            return '';
    }
    function __isset($name) {
        if ($name == "bar")
            return true;
    }
}
$foo = new Foo();
echo $foo->bar . PHP_EOL;  // outputs "" - correct
echo var_export(isset($foo->bar)) . PHP_EOL; // outputs "true" - correct

$bar = $foo->bar;

// outputs both "true" -- so the manual is wrong here
echo var_export(empty($foo->bar)) . PHP_EOL;
echo var_export(empty($bar)) . PHP_EOL;

Also see this bug report

Kaii
  • 20,122
  • 3
  • 38
  • 60
0

Apparently I didn't notice the link you included in your own question, so here's a basic breakdown of overloading:

Overloading in PHP is the concept of dynamically creating methods and parameters. Consider a basic scenario:

class MyClass {
  public $foo = 'bar';
}

$Instance = new MyClass();
echo $Instance->foo;

We would all expect that to print "bar," and it would. Here is that same example using overloding:

class MyOverloadedClass {
  public function __get($variable) {
    return $variable == 'foo' ? 'bar' : '';
  }
}

 $Instance = new MyOverloadedClass();
 echo $Instance->foo;

In this second example, because MyOverloadedClass::$foo does not exist, the __ge method will be executed, and will be passed the variable that the user asked for (in this case, "foo"). My code inside of the __get method would determine that the user is looking for foo, and return "bar"

Language constructs are parts of the PHP language. In other words, the parser interprets them and knows what to do, without having to lookup function references. Some examples are exit, die, print, echo, isset and empty.

isset() is the only language construct to work with overloading. The manual page describes an overloaded method __isset which you can add to your class, and will be executed every time someone calls isset on a property of that class. Calling empty() on an overloaded property, however, will always return true and likely throw an E_NOTICE. Here's why:

Disclaimer: calling empty() on an overloaded property DOES seem to execute __get(), IF AND ONLY IF you have an __isset() method that returns true for the passed variable name:

empty() will not call your overloaded __get() method. It will look in the class definition to see if that parameter exists. If it does, it'll evaluate whether or not it is empty. However, accessing undefined class parameters throws an error. In my first example, I would have thrown an error by asking for $Instance->bar, because it doesn't exist. This is the same error you would get if you asked for

empty( $Instance->foo );

In the second example. I hope this helps.

See the page you mentioned for additional details on how to apply this to functions, or setting variables.

Colin M
  • 13,010
  • 3
  • 38
  • 58
  • Kaii, view the bold text that says: Disclaimer: calling empty() on an overloaded property DOES seem to execute __get(), IF AND ONLY IF you have an __isset() method that returns true for the passed variable name My answer is as correct as the rest. The text after the disclaimer describes what happens when an isset is NOT present – Colin M Jun 16 '12 at 14:21