php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52825 return by reference with ternary operator causes notice "Only variable..."
Submitted: 2010-09-13 06:45 UTC Modified: 2010-09-13 13:34 UTC
From: mbroxer at post dot ru Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.3.3 OS: Windows XP SP3
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: mbroxer at post dot ru
New email:
PHP Version: OS:

 

 [2010-09-13 06:45 UTC] mbroxer at post dot ru
Description:
------------
I don't know if it's a bug, or that's how it should be, but it would be logical to assume that a ternary operator is equal to an IF block:

return $a ? $b : $c;
// ==
if ($a) return $b; else return $c;

I believe that's how it is in C. However when returning a reference, the first version produces a notice:
"Notice: Only variable references should be returned by reference"

It's hard to tell if this is normal behaviour or not, but it's confusing. If this is normal functionality, then I think this should be in documentation, at least in a form of a comment.

Test script:
---------------
class test {
	private $a = array();
	private $b = array();

	function &getA($key) {
		return $key > 0 ? $this->a[$key] : $this->b[$key]; 
		// the following line gives no notice
		// if ($key > 0) return $this->a[$key]; else return $this->b[$key];
	}
}

$a = new test;
$b = &$a->getA('1');

Expected result:
----------------
Notice: Undefined index: 1 in - on line 9

Notice: Only variable references should be returned by reference in - on line 9



Actual result:
--------------
Notice: Undefined index: 1 in - on line 9



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-09-13 06:46 UTC] mbroxer at post dot ru
I'm sorry, the expected result and actual result got mixed up when I was submitting. Expected is actual, and actual is expected.
 [2010-09-13 12:49 UTC] cataphract@php.net
-Status: Open +Status: Bogus
 [2010-09-13 12:49 UTC] cataphract@php.net
return $key > 0 ? $this->a[$key] : $this->b[$key];

is the same as

return ($key > 0 ? $this->a[$key] : $this->b[$key]);

C is not comparable because it has only pass and return by value.

This is documented in http://pt.php.net/ternary :

Note: Please note that the ternary operator is a statement, and that it doesn't evaluate to a variable, but to the result of a statement. This is important to know if you want to return a variable by reference. The statement return $var == 42 ? $a : $b; in a return-by-reference function will therefore not work and a warning is issued in later PHP versions.

See also http://stackoverflow.com/questions/3389928/can-you-pass-by-reference-while-using-the-ternary-operator/3390182#3390182
 [2010-09-13 13:34 UTC] mbroxer at post dot ru
Thank you for pointing me to that article, it's strangely placed in the chapter on Comparison operators, which Conditional operator isn't, so I haven't found it in the first place.

Well, although C does have pointers, what I meant was C++, which has references and ternary operator works with them. This code is perfectly valid and outputs 20, as expected:

#include <iostream>
using namespace std;

class test {
  public:
  int i, j;
  test():i(8),j(10){}
  int& a(int b) {
    return b == 2 ? i : j;
  }
};
int main() {
  test my;
  int& a = my.a(2);
  a += 12;
  cout << "Weekly Hours: " << my.a(2) << endl;
  return 0;
}

So, I still find it hard to follow the PHP logic in this. "the ternary operator is a statement, and that it doesn't evaluate to a variable, but to the result of a statement." -- but result of a statement is a variable. I suppose this has to do with some PHP internal specifics, which I am not aware of. But if this use of ternary operator doesn't work and produces a wrong result, then surely it should be a warning, not a notice.

But in any case, thank you again for your feedback, I'm mostly writing this comment for people who might research this subject in the future, maybe deciding to improve things, and I've no intentions to offend anyone in any way.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Jul 16 01:01:32 2025 UTC