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 this is not your bug, you can add a comment by following this link.
If this is your bug, but 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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 05:01:29 2024 UTC