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
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: olamedia at gmail dot com
New email:
PHP Version: OS:

 

 [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: Fri Dec 27 09:01:29 2024 UTC