php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #51280 Calculate expression before using it as argument
Submitted: 2010-03-12 08:45 UTC Modified: 2010-03-22 10:18 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: olamedia at gmail dot com Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.3.2 OS:
Private report: No CVE-ID: None
 [2010-03-12 08:45 UTC] olamedia at gmail dot com
Description:
------------
Calculate expression before using it as argument in function and with echo.

Test script:
---------------
class p{
	protected $_name = null;
	protected $_value = null;
	public function __construct($name, $value){
		$this->_name = $name;
		$this->_value = $value;
	}
	public function is($value){
		$this->_value = $value;
		return $this;
	}
	public function __toString(){
		return "$this->_name = $this->_value";
	}
}
class a{
	protected $_a = null;
	public function __set($name, $value){
		$this->_a[$name] = new p($name, $value);
		return $this->_a[$name];
	}
	public function __get($name){
		if (!isset($this->_a[$name])){
			$this->_a[$name] = new p($name, null);
		}
		return $this->_a[$name];
	}
}
class q{
	public function where($var){
		echo $var;
	}
}
$a = new a();
echo $a->x = 2; // "2" (Expected: "x = 2")
echo "\r\n";
echo $a->x; // "x = 2"
echo "\r\n";
$q = new q();
$q->where($a->x = 2); // "2" (Expected: "x = 2")
echo "\r\n";
$q->where(($a->x = 2)); // "2" (Expected: "x = 2")

Expected result:
----------------
x = 2
x = 2
x = 2
x = 2

Actual result:
--------------
2
x = 2
2
2

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-03-21 21:07 UTC] hholzgra@php.net
-Status: Open +Status: Bogus
 [2010-03-21 21:07 UTC] hholzgra@php.net
Expected behavior, see:

http://php.net/manual/en/language.operators.assignment.php

  [...]
  The value of an assignment expression is the value assigned. 
  That is, the value of "$a = 3" is 3.  
  [...]
 [2010-03-22 09:43 UTC] olamedia at gmail dot com
> the value of "$a = 3" is 3

Here I'm talking about function arguments, not a simple assignments.

function b($a){
  // here expected resulting object $a, not just int(3)
  var_dump($a);
}
class a{}
$a = new a();
b($a->x = 3); // outputs int(3)
$a->x = 3
b($a); // outputs object(a)#2 (1) { ["x"]=> int(3) }
 [2010-03-22 09:51 UTC] olamedia at gmail dot com
Sorry, my bad. This was an incomplete example. In first message there was a good 
example, when $a->x is an object, and in both cases: a($a->x) and a($a->x = 3) - I 
'm expecting object $a->x instead of assigned value because of __set() function, 
which converts value to an object.
 [2010-03-22 10:18 UTC] johannes@php.net
The order of the evaluation of function parameters is "undefined". (It actually changed with 5.2 or so due to performance reasons)
 [2010-03-22 10:30 UTC] olamedia at gmail dot com
Precalculation can be useful for ORM, for example, giving ability to use this 
construction:
$users->where($group->id = 2)

Also, this can be used for named parameters emulation:
class parameter{
  var $name;
  var $value;
  function __construct($name, $value){
    $this->name = $name;
    $this->value = $value;
  }
}
class parameters{
  var $data = array();
  function __set($name, $value){
    $this->data[$name] = new parameter($name, $value);
  }
  function __get($name){
    return $this->data[$name];
  }
}
function a(){
  var_dump(func_get_args());
}
$arg = new parameters();
a($arg->id = 3, $arg->x = 'some', $arg->y = 5);
 [2010-03-23 07:04 UTC] olamedia at gmail dot com
well, summarizing, I think that

1. any expression MUST be evaluated before it can be used (as parameter of 
function or anything).

2. it's buggy that __set() is not working in this special case.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 19:01:30 2024 UTC