|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #36214 __get method works properly only when conditional operator is used
Submitted: 2006-01-30 19:34 UTC Modified: 2007-01-10 16:01 UTC
From: pexu at lyseo dot edu dot ouka dot fi Assigned: dmitry
Status: Closed Package: Scripting Engine problem
PHP Version: 5.1.3-dev OS: Windows XP
Private report: No CVE-ID:
 [2006-01-30 19:34 UTC] pexu at lyseo dot edu dot ouka dot fi
When both __set and __get are set, conditional operator "?" fails to work when used to return variables from __get when working with arrays.

A normal if .. else clause however works fine. With non-array variables there's no problem, either.

If __set is not used, this bug doesn't seem to appear.

Reproduce code:
class overload
  private $array = array();
  public function __set($key, $value)
    $this->array[$key] = $value;
  public function __get($key)
    return isset($this->array[$key])
             ? $this->array[$key]
             : null;

$ol = new overload; $ol->arr = array();
array_push($ol->arr, "element");

Expected result:
array(1) {
  string(7) "element"

Actual result:
array(0) {


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2006-01-30 19:43 UTC]
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at and the instructions on how to report
a bug at

You're trying to acces a private property (arr) from 
outside the class. 
 [2006-02-02 14:08 UTC] pexu at lyseo dot edu dot ouka dot fi
Even overload::$array is defined as public variable, actual result remains the same. But if I change conditional operator to normal if .. else clause, problem disappers!

function __get ($key)
  if (isset($this->array[$key]))
    return $this->array[$key];
    return null;

works just fine. So the actual problem can't be a private property which is accessed outside the class, right?
 [2006-02-02 16:04 UTC]
That it works in the latter case is just a side affect which falls under "undefined behaviour".

You should actually see an error telling you that __get() can't return a reference or that array_push() wants a reference.

IIRC it's fixed in current CVS, could you please try?
Where "fixed" means that an error is generated.

 [2006-02-04 00:01 UTC] pexu at lyseo dot edu dot ouka dot fi
I quickly tried the newest snapshot (20060203, 5.1.3-dev) but  neither error messages were generated nor results were any different from 5.1.2. (Error_reporting was set to E_ALL | E_STRICT and display_errors was turned on. I tried both conditional operator and normal if clause.)

But I guess I can utilize ArrayObject etc. to get the expected result I wanted.
 [2006-02-06 10:32 UTC]
This is not a bug. Method __get() returns by value and it's result cannot be passed by reference.
 [2006-02-10 17:42 UTC] pexu at lyseo dot edu dot ouka dot fi
Sure it doesn't return a reference, but why this example still prints "5.1.3-dev This shouldn't work, but why are you seeing this text?"?

class a
  public $cond_oper = false,
         $array     = array();
  public function __set ($key, $value)
    return $this->array[$key] = $value;
  public function __get ($key)
    if ($this->cond_oper)
      return true ? $this->array[$key] : null;
      return $this->array[$key]; // This one works even though it shouldn't!
$a = new a; $a->a = array();
$a->a[] = "This shouldn't work, but why are you seeing this text?";
$a->cond_oper = true;
$a->a[] = "Nope, this text won't be displayed (which is ok).";
echo phpversion(), "\n", array_pop($a->a);

If I understood your explanations correctly, $a->a should've been an empty array and I should've seen two error messages telling me that __get method didn't return a reference etc.

PHP snapshot I used was built on Feb 10, 2006 15:30 GMT.
 [2006-11-28 03:24 UTC]
Is it the same issue? I suspect it to be the same but I'm unsure about the bogus state. I would like to have a little explanation, just to write a good work around if this is not a bug.

In this example, the first init raises a notice "Indirect modification of overloaded property context::$attachments has no effect" as the second works like a charm.

class context
  public $stack = array();

  public function __set($name,$var)
    $this->stack[$name] = $var;return;

  public function __get($name)
    if (!isset($this->stack[$name])) {
      return null;
    return $this->stack[$name];

$ctx = new context;
$ctx->comment_preview = array();
$ctx->comment_preview['content'] = '';
$ctx->comment_preview['rawcontent'] = '';
$ctx->comment_preview['name'] = '';
$ctx->comment_preview['mail'] = '';
$ctx->comment_preview['site'] = '';
$ctx->comment_preview['preview'] = false;
$ctx->comment_preview['remember'] = false;

$comment_preview = array();
$comment_preview['content'] = '';
$comment_preview['rawcontent'] = '';
$comment_preview['name'] = '';
$comment_preview['mail'] = '';
$comment_preview['site'] = '';
$comment_preview['preview'] = false;
$comment_preview['remember'] = false;
$ctx->comment_preview = $comment_preview;

 [2006-11-28 12:32 UTC]
As a confirmation of the reference problem, it works using an object (ArrayObject):
$ctx->comment_preview = new ArrayObject();
$ctx->comment_preview['content'] = '';
$ctx->comment_preview['rawcontent'] = '';
$ctx->comment_preview['name'] = '';
$ctx->comment_preview['mail'] = '';
$ctx->comment_preview['site'] = '';
$ctx->comment_preview['preview'] = false;
$ctx->comment_preview['remember'] = false;

It is getting rather confusing for the users. The bad point is this specific case is that ArrayObject is disabled with --disable-all... 
 [2007-01-10 16:01 UTC]
Fixed in CVS HEAD and PHP_5_2
PHP Copyright © 2001-2015 The PHP Group
All rights reserved.
Last updated: Sat Nov 28 11:01:33 2015 UTC