Exception handling for foreach using & Referencing in PHP

Source: Internet
Author: User

There are not many people using & referencing variables or objects or methods in PHP encoding, but & references can make your code simple and save resources. In this article, we focus on the exceptions and workarounds that occur with & in foreach.

$exp = [' name ' = ' test1 ', ' age ' = ', ' extension ' =            ' A:3:{s:4: ' nose '; s:4: "Long"; s:5: "Mouth"; S:3: "Big"; S:3: "Eye"; s:5: "Small";} ' ], [' name ' = ' test2 ', ' age ' = ', ' extension ' = ' a:3 ':            {s:4: "nose"; s:5: "Long2"; s:5: "Mouth"; s:4: "Big2"; S:3: "Eye"; S:6: "Small2";} ' ], [' name ' = ' test4 ', ' age ' = ', ' extension ' = ' a:3 ':            {s:4: "nose"; s:5: "Long2"; s:5: "Mouth"; s:4: "Big2"; S:3: "Eye"; S:6: "Small2";} ' ], [' name ' = ' test3 ', ' age ' = ', ' extension ' = ' a:3 ':            {s:4: "nose"; s:5: "Long3"; s:5: "Mouth"; s:4: "Big3"; S:3: "Eye"; S:6: "Small3";} '        ],        ];            foreach ($exp as & $v) {$extension = @unserialize ($v [' extension ']); $v [' nose '] = $extension [' Nose ']??            ""; $v [' Mouth'] = $extension [' Mouth ']??            ""; $v [' eye '] = $extension [' eye ']??        "";        } $NEWEXP = [];            foreach ($exp as $v) {if ($v [' mouth '] = = "Big3") {$newExp [] = $v;        }} dump ($NEWEXP); Exit

The functionality of this section of the code is described below:

1. Mix the extension fields in EXP into exp 2. If mouth is BIG3 in exp, the new array newExp3 is assigned. Output newexp

From the simple appearance to analyze the seemingly above logic is not wrong, and we predict the output should be the result of

... 0 = array:6 [    "Name" = "Test3"    "age" = "    extension" "=" a:3:{s:4: "Nose"; s:5: "Long3"; s:5: " Mouth "; s:4:" Big3 "; S:3:" Eye "; S:6:" Small3 ";}"    " Nose "+" long3 "mouth" + "    big3"    "eye" + "Small3"  ]  ... But the result is not what we predict, the result of the program output is:  []  This is why, we have to analyze each

Exception thrown by a foreach reference

The first foreach is the following block of code

foreach ($exp as & $v) {     $extension = @unserialize ($v [' extension ']);     $v [' nose '] = $extension [' Nose ']?? "";     $v [' mouth '] = $extension [' Mouth ']?? "";     $v [' eye '] = $extension [' eye ']?? "";}

, &v is used in this code block. Because the only thing we need to do in this step is to handle the data in the array itself, so using references is less memory consuming. In the execution of the program

V should be a reference to the last element of exp.
Then when we modify the value of $v, the last element of exp should change. And there is a very important problem is that the reference after the use of the foreach reference after the end of the foreach still exists. In addition to the above foreach, $v still references the last element of exp.

Does the $v still exist after foreach

. foreach ($exp as & $v) {    $extension = @unserialize ($v [' extension ']);    $v [' nose '] = $extension [' Nose ']?? "";    $v [' mouth '] = $extension [' Mouth ']?? "";    $v [' eye '] = $extension [' eye ']?? "";}  Dump ($v); the output is: array:6 [  "Name" = "Test3"  "age" = "  extension" = "a:3:{s:4:" Nose "; s:5:" Long3 "; s:5:" Mouth "; s:4:" Big3 "; S:3:" Eye "; S:6:" Small3 ";}"  " Nose "=" "Long3"  "mouth" + "big3" "Eye" and "  Small3"

Second cycle analysis

$NEWEXP = []; foreach ($exp as $v) {     if ($v [' mouth '] = = "Big3")         {$newExp [] = $v;     }} dump ($NEWEXP);

Here we are doing a regular loop to loop exp and in that loop we are using a variable that does not use a reference. The difference is $v and &$v please look carefully.
In this loop, the $v is still a reference to the last element of exp. So in the loop in fact each time is the award exp current value is assigned to $v because the reference relationship ultimately changes the value of the last element of exp. 那么在foreach中exp最后子元素的值一直是变的。演变过程如下:

In order to briefly represent//the first cycle exp becomes: That is, the first element is assigned to the last element [[' Name ' = ' test1 ', ...], [' name ' = = ' Te    St2 ', ...], [' name ' = ' test4 ', ...], [' name ' = ' test1 ', ...        ],]//the second cycle exp becomes: That is, the second element is assigned to the last element [[' Name ' = ' test1 ', ...], [' name ' = ' test2 ', ...], [' name ' = ' test4 ', ...], [' name ' = ' test2 ', ...],]//third The secondary loop exp becomes: That is, the third element is assigned to the last element [[' Name ' = ' test1 ', ...], [' name ' = ' test2 ',.    .. ], [' name ' = ' test4 ', ...], [' name ' = ' = ' test4 ', ...]],]//the fourth cycle exp becomes: the first The four-element assignment gives the last element a loop complete [[' Name ' = ' test1 ', ...], [' name ' = ' test2 ', ...] , [' name ' = ' test4 ', ...], [' name ' = ' test4 ', ...],

Cause analysis

From the above can be seen although the last element of exp compound if condition in the $v [' mouth '] = = "Big3" , but the last element in the loop itself has become the third element, so the MOUTH=BIG3 element does not exist. This process is a bit around and can be read more than once. Of course you can also look at the implementation of the foreach in PHP's Zend engine and see the VLD intermediate code, such as the VLD of a simple loop

Number of ops:16compiled VARs:!0 = $arr,! 1 = $key,!2 = $rowline # * OP fetch   Ext return operands---------------------------------------------------------------------------------2 0 >                                Init_array ~0 1 1 add_array_element                                ~0 2 2 add_array_element ~0 3 3 add_array_element      ~0 4 4 add_array_element ~0 5 5                                         ASSIGN! 0, ~0 4 6 > Fe_reset          $0,->14 7 > > Fe_fetch,->14                                                   8 > Zend_op_data 9 ASSIGN !2, $ ASSIGN! 1, 5 ECHO    !1 ECHO!2 6 13                                              > JMP->7 > Switch_free $7 > RETURN 1
Related Article

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.