php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #46599 __call() and __set() priority
Submitted: 2008-11-18 02:25 UTC Modified: 2008-11-19 15:26 UTC
From: benjiro at benjiro dot com Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5.2.6 OS: Linux Debian Lenny
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: benjiro at benjiro dot com
New email:
PHP Version: OS:

 

 [2008-11-18 02:25 UTC] benjiro at benjiro dot com
Description:
------------
Unless my definition off the magic methods __call, and __set are wrong, there seems to be a conflict between both.

When both __set & __call are defined, the __set method overrides __call, even when the object in question is a clearly defined method.

Line1: $object->xxx( 'yyy', 'ooo' ); // At this point, __set will dominate any call, while its clearly a method.
Line2: $object->xxx = zzz;

One expects that a method call can be recognized with (), yet, __set has a higher priority, and thinks you are calling $object->xxx on line 1, breaking the correct resolving to find out that its really a methode.

Reproduce code:
---------------
<?

$object = new test();
  // Create john with lastname, smith, and say hello. Note: we are not doing anything with smith in this example.
$object->john( 'smith' )->hello(); 
  // Lets set a changed value to the changed list of object.
$object->john = xxx;

class test {
  private $changed = array();

  function __call ( $name, $args ) {
    $this->{$name} = new child();
    return $this->{$name};
  }

  function __get ( $name ) {
    if ( isset( $this->{$name} ) )
      return $this->{$name};
  }

  function __set ( $name, $value ) {
    echo 'Lets register a possible changed value';
    if ( isset( $this->{$name} ) )
      $this->changed[$name] = $value;
  }
}

class child {
  function hello () {
    echo 'Hello, im tests son, called john';
  }
}

?>

Expected result:
----------------
Expected:

Hello, im tests son, called john
Lets register a possible changed value



Actual result:
--------------
Actual result is:

Lets register a possible changed value
Fatal error: Call to a member function hello() on a non-object in /xxx/index5.php on line 5

Line 5 is in reality the method...



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-11-19 15:26 UTC] lbarnaud@php.net
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

Retrieving a variables not declared in the class definition calls __get(). (test with "public $john;" added in the class).

You should use an internal storage (e.g. $this->childs[$name]) instead of $this->$name directly.

 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Fri Mar 14 15:01:30 2025 UTC