PHP Reference Pass-PHP function Reference parameter group: function set (array & $array, $path, $value)

Source: Internet
Author: User
function set(array &$array, $path, $value){    print_r($array);    echo('
'); $segments = explode('.', $path); while(count($segments) > 1) { $segment = array_shift($segments); if(!isset($array[$segment]) || !is_array($array[$segment])) { $array[$segment] = []; } $array =& $array[$segment]; print_r($array); echo('
'); } $array[array_shift($segments)] = $value; print_r($array); echo('
');}$arr = ['a' => 1, 'b' => 2, 'c' => 3];set($arr, 'a.b.d', 4);print_r($arr);

Results:

Array ([A] = 1 [b] = 2 [c] = 3)

Array ()

Array ()

Array ([d] = 4)

Array ([a] = = Array ([b] = = Array ([d] + 4)) [B] = 2 [c] = 3)

Why the final result is not an array ([d] = 4), but an array ([a] = = Array ([b] = = Array ([d] = 4)) [B] = 2 [c] = 3)?
How to solve this: $array =& $array [$segment];

Reply content:

function set(array &$array, $path, $value){    print_r($array);    echo('
'); $segments = explode('.', $path); while(count($segments) > 1) { $segment = array_shift($segments); if(!isset($array[$segment]) || !is_array($array[$segment])) { $array[$segment] = []; } $array =& $array[$segment]; print_r($array); echo('
'); } $array[array_shift($segments)] = $value; print_r($array); echo('
');}$arr = ['a' => 1, 'b' => 2, 'c' => 3];set($arr, 'a.b.d', 4);print_r($arr);

Results:

Array ([A] = 1 [b] = 2 [c] = 3)

Array ()

Array ()

Array ([d] = 4)

Array ([a] = = Array ([b] = = Array ([d] + 4)) [B] = 2 [c] = 3)

Why the final result is not an array ([d] = 4), but an array ([a] = = Array ([b] = = Array ([d] = 4)) [B] = 2 [c] = 3)?
How to solve this: $array =& $array [$segment];

First, if $array =& $array[$segment] the symbol in the statement is & removed, the result is like the final output expected by the landlord Array([d] => 4) . Obviously the crux of the problem is on top of that sentence & .
We know that php two data structures are used when storing the values of variables and variables zval zval_value . zvalcontains four fields in:
refcount_gcRepresents a reference count
is_ref_gcIndicates whether it is a reference
valueStore variable identifiers
typeSpecific types of variables

The actual value of the variable is stored in another union, and the concrete structure is omitted. Now let's simulate the process:
First of all$arr = ['a' => 1, 'b' => 2,'c' => 3]Create:
arr{'refcount_gc':1, 'is_ref_gc':0,'value':'arr','type':array}(The writing of value and type is omitted later, and the zval_value of the array type is created.)
['a']{'refcount_gc':1, 'is_ref_gc':0, ...}
['b']{'refcount_gc':1, 'is_ref_gc':0, ...}
['c']{'refcount_gc':1, 'is_ref_gc':0, ...}
In the callsetmethod, you pass the$arrA reference to:&arr{'refcount_gc':2, 'is_ref_gc':1, ...}
And then into the function body,whileWithin the loop, for the first time due to!is_array($arr['a'])Established, for$arr['a']An empty array is assigned.
['a']{'refcount_gc':1, 'is_ref_gc':0, ...}, and create a zval_value of type array.
$arr =& $arr['a'];This sentence again will be the original array of['a']Convert to reference['a']:{'refcount_gc':2, 'is_ref_gc':1, ...}, it andarrBoth are reference ① for this empty array.
Then the second loop, because Arr is a reference to an empty array at this point,!isset($arr['b'])Established, for$arr['b']An empty array is assigned.
arr['b']{'refcount_gc':2, 'is_ref_gc':1, ...}and creates a zval_value of type array, and since ①, the original array's['a']is also a reference to this empty array, that is, in the original array['a']On the basis of a['a']['b']Ii.
$arr =& $arr['b'];This sentence will againarr['b']Convert to referencearr['b']:{'refcount_gc':3, 'is_ref_gc':1, ...}, because the empty array in the ②,①['b'], the original array of['a']['b']And arr are both reference ③ for this empty array.
Then exit the loop.
$arr['d'] = 4;To create an index for an empty array in ②['d'], and because of ③, the original array['a']['b'], the array in the ①['b']It's also a reference to this array, and they all point to this(['d'] => 4)The array.
So the final print of the original array isArray ( [a] => Array ( [b] => Array ( [d] => 4 ) ) [b] => 2 [c] => 3 )

The simplified illustrations are:

The painting is more casual. Roughly follow the digital steps to embody its process ...

The problem arises mainly in

 while(count($segments) > 1)    {        $segment = array_shift($segments);        if(!isset($array[$segment]) || !is_array($array[$segment]))        {            $array[$segment] = [];        }        //这里传引用赋值,将$array[$segment]的引用传给了$array        //所以此后的$array已经不再指向传参近来的那个$array(但传参进来的那个$array并未消失)        //最简单的方法是将这个&去掉,在输出一遍,你应该就明白了        $array =& $array[$segment];        print_r($array);        echo('
'); }

Run, if you do not understand the problem can leave a message

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.