php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79218 inconsistent behavior since call time pass by reference was removed
Submitted: 2020-02-04 10:41 UTC Modified: 2020-02-05 11:44 UTC
From: skullnobrains at gmail dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.3.14 OS: linux and probably all
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: skullnobrains at gmail dot com
New email:
PHP Version: OS:

 

 [2020-02-04 10:41 UTC] skullnobrains at gmail dot com
Description:
------------
creating a variable on the fly and passing it by reference produces a run-time notice which is inconsistent with the actual behavior, since it does work and the notice is not a deprecation.

passing a value produces a compile-time fatal error

both messages are hardly distinguishable

i picked the php version at random but all php7 versions and possibly 6 are concerned



Test script:
---------------
$sock=stream_socket_client('tcp://www.php.net:80') or die();
$num=stream_select($R=array(),$W=array($sock),$O=array(),1) or die("selected : ".var_export($num,true));
var_dump($W);

------

$sock=stream_socket_client('tcp://www.php.net:80') or die();
$W=array($sock);
$num=stream_select(null,$W,null,1) or die("selected : ".var_export($num,true));
var_dump($W);

Expected result:
----------------
first script should just work : i am passing variables, not values.

second script : i'd rather it worked ( preferably with the previous explicit, convenient, and backwards compatible '&$whatever' syntax ) but unfortunately can't file the behavior as a bug.

Actual result:
--------------
PHP Notice:  Only variables should be passed by reference in /home/alex/bugreport.php on line 4
PHP Notice:  Only variables should be passed by reference in /home/alex/bugreport.php on line 4
PHP Notice:  Only variables should be passed by reference in /home/alex/bugreport.php on line 4
array(1) {
  [0]=>
  resource(5) of type (stream)
}

------------------

PHP Fatal error:  Only variables can be passed by reference in /home/alex/bugreport.php on line 7


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-02-04 10:43 UTC] nikic@php.net
-Status: Open +Status: Not a bug -Package: PHP Language Specification +Package: Scripting Engine problem
 [2020-02-04 10:43 UTC] nikic@php.net
Assignment does not return a reference.
 [2020-02-04 13:19 UTC] skullnobrains at gmail dot com
it does : the code works and the array is modified by stream_select() as demonstrated.

if stream_select is able to modify a non-reference, maybe this is a different bug.

either it should not work at all, or there should be no notification.
 [2020-02-04 13:25 UTC] nikic@php.net
I don't see any array being modified in your example. $W is initialized to [$sock] and stays that way -- the fact that this matches what the function would set it to is coincidental.
 [2020-02-04 13:28 UTC] skullnobrains at gmail dot com
my bad, the array is not modified.

still the behavior is very unclear and totally inconsistent between a simple runtime notification and a non working code and a fatal error at compile time if those are actually identical case.
 [2020-02-04 20:42 UTC] a at b dot c dot de
Because in

$num=stream_select($R=array(),$W=array($sock),$O=array(),1)

you're not passing variables to stream_select, you're passing assignment expressions, which are not variables. (If they were variables, you'd expect to be able to assign values to them: ($R = array()) = 17; would assign 17 to the variable "$R = array()").

More accurately, you're passing the values that those assignment expressions evaluate to (which are arrays, not variables); as it happens you're also assigning those same values to some variables, but that's a side-effect of the evaluation.
 [2020-02-05 11:43 UTC] skullnobrains at gmail dot com
noted.
thanks for your answer. i get this syntax has become wrong.

you may note that the &$R=array(...) idiom used to work as one may think intuitively : affect array to the $R variable and pass a reference to $R to the func.

so that's a side effect of loosing call time pass by reference which used to make the pass by value and pass by reference syntaxes consistent.

but then since passing a value is forbidden and otherwise produces a fatal compile time error, it definitely also SHOULD be detected by the parser at compile time and produce the same behavior.

i know this is not the place, but +1 vote for reverting that very useful feature that made all those behaviors explicit and allowed the developer to knowingly use either values or references depending on use cases. this also allowed to extend functions easily without breaking existing code.
 [2020-02-05 11:45 UTC] skullnobrains at gmail dot com
IS_A_BUG
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Sun Apr 11 04:01:24 2021 UTC