php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74509 array_shift($foo) throws "null given" instead of "Undefined variable"
Submitted: 2017-04-28 16:15 UTC Modified: 2017-05-01 15:32 UTC
From: pov at fingerprint dot fr Assigned:
Status: Not a bug Package: Variables related
PHP Version: 5.6.30 OS:
Private report: No CVE-ID: None
 [2017-04-28 16:15 UTC] pov at fingerprint dot fr
Description:
------------
When applying array_shift on a non-existing variable, a warning about array_shift is emitted (array_shift() expects parameter 1 to be array, null given) instead of a notice on the non-existing variable.

Tested on all the  following packaged versions :
7.0.17-2+deb.sury.org~trusty+1
7.1.3-2+deb.sury.org~trusty+1
5.5.38-4+deb.sury.org~trusty+1
5.6.30-7+deb.sury.org~trusty+1


-- Additional tests
This bug probably applies on other functions as well.
Some tests gives interesting results (I note NUV = Notice : Undefined variable - ok -, WNG = Warning : null given - which shouldn't be)  :

array_shift($foo)             WNG
array_slice($foo)                     NUV
array_unshift($foo, 1)        WNG 
array_unshift($foo, $bar)             NUV bar (logically, should be NUV $foo first)
array_pop($foo)               WNG
array_sum($foo)                       NUV
empty($foo)                   returns true
htmlentities($foo)                    NUV


Test script:
---------------
error_reporting(E_ALL | E_NOTICE);
ini_set('display_errors', true);

echo '$foo = '; echo $foo; echo "\n";
echo 'array_shift($foo) = '; echo array_shift($foo); echo "\n";
exit;


Expected result:
----------------
$foo =	
	Notice: Undefined variable: foo in index.php on line 4

array_shift($foo) =
	Notice: Undefined variable: foo in index.php on line 4

Actual result:
--------------
$foo =	
	Notice: Undefined variable: foo in index.php on line 4

array_shift($foo) =
	Warning: array_shift() expects parameter 1 to be array, null given in index.php on line 5


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-04-28 16:55 UTC] requinix@php.net
-Status: Open +Status: Not a bug -Package: PHP Language Specification +Package: Variables related
 [2017-04-28 16:55 UTC] requinix@php.net
All those functions have one thing in common: the argument is by reference. PHP does not issue warnings when creating references to variables that do not exist, which is why code like

function add($a, $b, &$c) {
  $c = $a + $b;
}
add(1, 2, $sum);

works without problems.

Changing that as a whole would create many warnings out of nowhere for use cases that were easily justifiable before. The alternative would be a number of tweaks throughout PHP to make (some) functions that use references warn if the variable did not already exist, but given that the purpose would be to turn a clear E_WARNING into the less severe (and often ignored) E_NOTICE, I don't think doing so is worth it.
 [2017-05-02 08:41 UTC] pov at fingerprint dot fr
You're right, I didn't thought the explanation could have been so simple as the parameter being a reference.

This is probably why (I'm not suggesting PHP should do the same) some languages have parameter direction specification (in / out / in & out).

Why I opened this bug is that, in case of a typo in the variable name, it can lead to spending time searching for a bug where it isn't.

* in the present case, it throws an E_WARNING because array_shift only works on an array. But there may be cases where the operation is valid on NULL and won't generate any error.

* suppose we've got :
function add(&$sum, $number) {
  $sum += $number;
}

$sum_variable_with_a_long_name = 10;
add($sum_varable_with_a_long_name, 15); // The developper forgot, or accidentally dropped, an 'i'

echo $sum_variable_with_a_long_name; // 10  ! He shouts "WHAT'S GOING ON ?"


Without adding parameter-direction specification to the language specification, a (long) way to change this behaviour would be to 
- store the fact the variable is unknown in the reference
- when reading the referenced variable, throw the appropriate E_NOTICE rather than using null as value
In other terms, if you reference an non-existing variable, you have the right to write to it, not to read from it.
Many work for, effectively, something that probably don't deserve it.

Thanks for your response and your time.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 15:01:28 2024 UTC