php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #29767 Weird behaviour of __set($name, $value);
Submitted: 2004-08-20 03:55 UTC Modified: 2005-02-02 08:20 UTC
Votes:2
Avg. Score:3.5 ± 1.5
Reproduced:1 of 2 (50.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: morten at nilsen dot com Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.0.1 OS: Linux
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: morten at nilsen dot com
New email:
PHP Version: OS:

 

 [2004-08-20 03:55 UTC] morten at nilsen dot com
Description:
------------
The attached script behaves ilogically


Reproduce code:
---------------
<?php
  class template {
    function __set($name, $value) {
      echo "Set $name to $value<br>";
      if($name[0] != '&') $name = '&'.$name.';';
    }
  }

  function fetchlist($name) {
    global $template;

    echo '$template->what = '.$name.'<br>';
    $template->what = $name;

  } 

  $template = new template();
  fetchlist('user');
  fetchlist('group');
?>

Expected result:
----------------
$template->what = user
Set what to user
$template->what = group
Set what to group

Actual result:
--------------
$template->what = user
Set what to user
$template->what = group
Set &what; to group

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-08-20 04:16 UTC] morten at nilsen dot com
(obvious) workaround is to change:

  if($name[0] != '&') $name = '&'.$name.';';

into:

  $entity = "&$name;";
 [2004-08-20 04:52 UTC] morten at nilsen dot com
further weirdness uncovered with this code;

<?php
  class test {
    function __set($name, $value) {
      $name = $name.$value;
      echo "$name<br>";
    }
  }

  $test = new test;
  $test->kake = 1;
  $test->kake = 2;
  $a = 3;
  $test->kake = $a;
  $a++;
  $test->kake = $a;
  for($a = 0; $a < 10; ++$a)
    $test->kake = $a;
?>
 [2005-01-25 20:55 UTC] eric-php at famderuiter dot net
This problem can also be seen in __get

test case:
---------------------

<?php

class Test {

  private $group_id = 1;
  private $group_name = 'test_group';

  public function __get($name) {
    echo "get $name called\n";
    $name = 'group_' . $name;
    return $this->$name;
  }

  public function __set($name, $value) {
    echo "set $name, $value called\n";
    $name = 'group_' . $name;
    $this->$name = $value;
  }
}

$test = new Test();
for ($i=0; $i<2; $i++) {
  echo $test->name . "\n";
  $test->name = $i;
}

?>

Output:
----------------------
get name called
test_group
set name, 0 called

Fatal error:  Cannot access private property Test::$group_name in /var/www/AAF/bug.php on line 23

Expected Output:
-----------------------
get name called
test_group
set name, 0 called
get name called
0
set name, 1 called

What is happening here?
-------------------------
It looks like the 'name' argument in both __get and __set is passed by reference. 
Clearly this should not be happening because it allows code morphing and the error messages are very confusing (eg: Cannot access private property Test::$group_name in /var/www/AAF/bug.php on line 23 <= there is no reference to $group_name on that line .. only to name .. took me a while to figure out what was wrong)
 [2005-02-02 08:20 UTC] dmitry@php.net
Fixed in CVS (HEAD and PHP_5_0).
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Jan 22 13:01:32 2025 UTC