php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #64755 Only variables should be passed by reference
Submitted: 2013-05-02 08:03 UTC Modified: 2013-09-11 23:28 UTC
From: eth at ethaniel dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.4.14 OS: Debian 7.0
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: eth at ethaniel dot com
New email:
PHP Version: OS:

 

 [2013-05-02 08:03 UTC] eth at ethaniel dot com
Description:
------------
I get a "PHP Strict Standards:  Only variables should be passed by reference in" 
error where there should be none.

Test script:
---------------
echo array_pop(array_keys(array("erwre")));

Expected result:
----------------
Result: 0.

Actual result:
--------------
The script returns the result (0), but also a "PHP Strict Standards:  Only 
variables should be passed by reference in" in my error log.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-05-02 08:25 UTC] pajoye@php.net
-Status: Open +Status: Not a bug
 [2013-05-02 08:25 UTC] pajoye@php.net
See www.php.net/array_pop.

Using: array_pop(array_keys($a)); array_keys($a) is an expression while array_pop 
expects a variable. ($k = array_keys($a);...).
 [2013-09-11 22:59 UTC] guy at syntheticwebapps dot com
I have a different example than the one given. Consider:

function myfunc( &$refvar ) {
  ...
}

$horse = myfunc( $value = array() );

The code example above also gets the same exception, however, this does not seem 
correct. This suggests that the type of "$value = array()" is expression and not 
a variable. But this violates an assumption in the language. Is this assumption 
incorrect? Should it be incorrect?

As in the original reported form of the problem, I believe there should be some 
forgiveness in the call-by-reference receiver. I can understand why NOT to do 
that, but there are safe ways to do it anyway, like create a new zval for local 
use. 

But it's more important to me that $value = array() evaluates to the VARIABLE 
$value and NOT an expression. What expression could it possibly represent? The 
supposed expression in such a case is meaningless, whereas the variable is 
meaningful and useful. Any chance this could be fixed in future?
 [2013-09-11 23:13 UTC] guy at syntheticwebapps dot com
Even worse, the following no longer works in PHP 5.4+ and this is an ERROR 
exception: 

$dbentry = array_shift(array_splice($dbents, $x, 1)))

This is why some leeway is appropriate on this error. I you can't chain together 
such logical progressions without INVENTING a variable in the code which has no 
other purpose than to avoid this ERROR exception, the language is headed the 
wrong direction and causing limitations for no cause.

I really think this needs to be fixed.
 [2013-09-11 23:28 UTC] nikic@php.net
array_shift(array_splice($dbents, $x, 1)) does not throw an ERROR exception (whatever that is). It throws an E_STRICT level error, which is the lowest error type we have.

The E_STRICT tells you that you have some code that currently works, but is discouraged. What you were actually looking for is array_splice($dbents, $x, 1)[0] (at least I assume so, because I don't really get your code sample.)
 [2013-09-12 01:41 UTC] guy at syntheticwebapps dot com
To respond to eth: I'm not disagreeing with you, but just keep in mind that 
before 5.4, func()[$index] was not legal syntax, so it made a lot of sense to 
use phrasing like array_shift(array_splice(...)). So there's a bunch of code out 
there that uses the old approach, and in 5.4+ it's no longer considered OK. 

I'm just asking: Why should it not be OK? This example around arrays is not the 
only one, so the syntax you suggested will not apply to all cases. It seems 
unduly inflexible to disallow values to be passed in where reference aliasing is 
intended. So what if the caller intends to disregard the response? Why force 
them to "care enough" to create a variable of their own when that only serves to 
delay the freeing of that value from memory by one level of the call stack? Fact 
is, functions have side effects and return values and other call-by-reference 
parameters which may be what the caller is really looking for. The caller 
shouldn't need to pretend to care about every value they pass to a function 
which deems it reference aliasable.

I realize here I'm going deeper into PHP history. I just think it's an 
improvement along positive lines to relax this and not move toward strictness 
for non-utilitarian reasons. Today's E_STRICT becomes tomorrow's E_DEPRECATED 
and next week's E_ERROR. So why be picky about this when there's no ambiguity?
 [2013-10-07 00:12 UTC] a at b dot c dot de
For guy's example. Yes, your assumption is wrong; the suggestion 'that the type of "$value = array()" is expression and not a variable' is correct. It's not a variable, it's an assignment expression.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 22 09:01:29 2024 UTC