Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP core function arguments; manual says reference, however it accepts values

I've noticed some inconsistencies in the PHP manual; a number of core function signatures are documented to accept arguments by reference, however they accept arguments by value.

I posted a more specific question previously, and @cweiske provided a great answer (with reference to the pertinent PHP source) however these inconsistencies appear to be more rampant.

There are a number of functions that are affected by this (I'll update this list as warrants; also note, these tests were done in an error_reporting(-1) environment)

  • http://www.php.net/manual/en/function.current.php
    • This was already discussed at the linked question
  • http://www.php.net/manual/en/function.key.php
    • This was already discussed at the linked question
  • http://www.php.net/manual/en/function.array-replace-recursive.php
    • array array_replace_recursive ( array &$array , array &$array1 [, array &$... ] )
    • Accepts arguments $array, $array1, etc., by value. This has been corrected.
  • http://www.php.net/manual/en/function.array-multisort.php
    • bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC [, mixed $arg = SORT_REGULAR [, mixed $... ]]] )
    • Accepts arguments $arr, etc., by value. This should throw an error, as it won't do anything if the argument isn't a variable.

Now I'm concerned, not because I'm being anal about the documentation, but because I fear that PHP devs are on the fence about the implementation details of these functions (or something equally unreliable)

I use array_replace_recursive() for instance, to take an array argument, and apply it against another array containing defaults. Some of my codebase has taken advantage of this inconsistency, to simply do:

$values = array_replace_recursive(array(
    'setting_1' => array(
        'sub-setting_1' => '',
        'sub-setting_2' => '',
        'sub-setting_3' => '',
     ),
    'setting_2' => array(
        'sub-setting_1' => 0,
        'sub-setting_2' => 0,
     ),
     'setting_3' => true,
), $values);

Thus producing a properly formatted array (to get around gratuitous isset() calls)

Should I be concerned with this? I'm thinking about submitting a documentation related bug request, but I'm first curious if anyone on SO (looking in your direction @cweiske) has insight on why this has been done.

like image 522
Dan Lugg Avatar asked Nov 04 '22 16:11

Dan Lugg


1 Answers

Perhaps I'm not understanding your dilemma, but those functions don't directly modify the data in their parameters, so whether they accept via reference or value is sort of a moot point isn't it? Either way you're going to need to assign the return value if you want the function call to actually do anything for you.

In terms of insight into why you might be seeing the discrepancy. PHP 5 has had many changes made to the way references work. In fact I believe it's PHP 5.3+ that no longer permits certain usages of & to assign by reference. What you may be seeing is the transition of some of the PHP core functions to comply with the new rules about reference assignment. If memory serves me, PHP 5.3 branch was actually intended to be PHP 6, but was decidedly merged into the trunk as a branch instead of waiting for several complex features to be finished. This would account for why you've never seen confusion like this before in PHP.

like image 136
Brian Avatar answered Nov 15 '22 04:11

Brian