Pointer tips in PHP array _ PHP Tutorial

Source: Internet
Author: User
Small pointer thinking in the PHP array. Recently, I encountered a very strange problem in my work. after using the each function to traverse an array, I passed the array as a real parameter to a function, I encountered a very strange problem in using the function again recently. after using the each function to traverse an array, I passed the array as a real parameter to a function, in the function, use each to traverse the form parameter array again. The purpose of using the each function twice is to convert the key in the array to the variable name, and the value corresponding to the key to the variable value. In fact, this function can be implemented using the extract function. Next, let's talk about what problems occurred when using the each function inside the function. after traversing, we found that some variables are NULL, that is, some variables are lost. I don't know whether the description is clear. I 'd like to simplify the problem at work and explain it with the following code.

 1, 'var2' => 2, 'var3' => 3, 'var4' => 4, 'var5' => 5); while (list ($ key, $ value) = each ($ arr) {$ key = $ value;} // the following operations are critical. the problem lies here. after traversing, add a value to the array. $ Arr ['var6'] = 6; func ($ arr); function func ($ arrtmp) {while (list ($ key, $ value) = each ($ arrtmp )) {$ key = $ value;} var_dump ($ var1); var_dump ($ var2); var_dump ($ var3); var_dump ($ var4); var_dump ($ var5 ); var_dump ($ var6) ;}?>

Output: NULL int (6 ).

According to the general idea, the $ var1, $ var2, $ var3, $ var4, $ var5, and $ var6 variables in the function func should all have them, but this is not the case, only the variable $ var6 has a value, while the other variables are NULL. Why?

The problem lies in the array pointer that we will discuss today. The each function returns the elements pointed to by the current array pointer in the form of an array, and moves the array pointer one forward to the next array unit. After we use the each function to traverse the array $ arr, the internal pointer of the $ arr array has pointed to the next bit of the last unit (with no value ). At this time, we executed the $ arr ['var6'] = 6 operation and added a new unit to the array. we know that, arrays stored in the memory must be sequential address units. That is to say, the position of $ arr ['var6'] in the memory should be the unit pointed to by the current array pointer (previously empty ). In addition, assigning values to an array does not move the internal pointer of the array. after assigning values, the $ arr array pointer is changed from pointing to a NULL to pointing to an address unit with an actual value.

There is another rule for passing an array as a parameter between functions: We know that when a function is called, the system will assign a copy of the real parameter to the form parameter (except for reference calls ), for arrays, we not only copy the values of real parameters, but also copy the position of the current internal pointer of the real parameter array. If the internal pointer of the real parameter points to the end of the array, the system resets the internal pointer of the parameter to the first unit of the parameter group. if the internal pointer of the real parameter is not at the end of the array, that is, it points to a valid unit. then, the system points the array pointer position of the form parameter to an array unit with the same value as the array pointer of the real parameter.

If you do not perform the $ arr ['var6'] = 6 operation, all the six variables ($ var1-$ var6) have a value, because after each, the array pointer has already pointed to the end of the array. when the func () function is called, the system resets the $ arrtmp array pointer and points it to the first element. But after $ arr ['var6'] = 6, everything changes, this operation changes the $ arr array pointer from pointing to a NULL value to a valid value (note: Before and after the value assignment, the address that the array pointer points to is unchanged, but before the value assignment, there is no address unit, and after the value assignment is changed to 6 ). This causes the $ arr array pointer to point to a valid unit. when the func () function is called, the system will not reset the $ arrtmp array pointer, the $ arrtmp array pointer will be the same as the $ arr array pointer, pointing to his own last unit. The each function starts from the position of the current array pointer. Therefore, the return value of the first result of the each function operation is the last element of the array $ arrtmp. it moves the array pointer down and the while loop ends here, therefore, $ arrtmp ['var1']-$ arrtmp ['var5'] is not traversed, resulting in $ var1-$ var6 being NULL.

Changes in the pointer of each array during the assignment process. Let's give a conclusion first, and then let's use the code to prove this conclusion. $ Arrtmp = $ arr; in this value assignment expression, I call $ arr a value array and $ arrtmp a value array. When assigning values to a number Group, if the array pointer of the value-assigned array has already pointed to the end of the array, the array pointer of the value-assigned array will be reset, pointing to the first element of the array; if the array pointer of the value-assigned array does not point to the end of the array but to any valid array element, the array pointer of the value-assigned array will not be reset, instead, it retains the elements it originally points. After a value assignment, the assigned array not only has the value of the assigned array, but also the array pointer of the assigned array points to that element. the assigned array also points to the element with the same value.

Demo1:

 1,'var2'=>2,'var3'=>3,'var4'=>4,'var5'=>5);while( list($key,$value) = each($arr) ){if($value == 4) break;}var_dump(current($arr));$arr1 = $arr;var_dump(current($arr));var_dump(current($arr1));?>

The execution result of demo1 is: int (5) int (5) int (5 ). The result shows that the position of the $ arr array pointer has not changed before and after the value assignment. $ arr1 not only has the same value as $ arr, but also has the same element value as $ arr. Now we can use the above conclusions to explain this result. in the while loop, there is an if judgment statement to prevent the $ arr array pointer from pointing to the end of the array, but keep it in a valid position. When $ value = 4, the loop will jump out, and the each function will move the array pointer one byte forward, which leads to the $ arr array pointer pointing to 5th elements, therefore, before assigning a value, current ($ arr) returns 5. after assigning a value, because the current pointer of $ arr does not point to the end before assigning a value, therefore, after a value is assigned, the array pointer of $ arr is not reset, but its original position is retained. Therefore, after the value is assigned, the result of using current ($ arr) is still 5. When a value is assigned, $ arr1 not only obtains the value of $ arr, but also points to the same element as $ arr, both of which are 5.

Demo2:

 1,'var2'=>2,'var3'=>3,'var4'=>4,'var5'=>5);while( list($key,$value) = each($arr) ){    //if($value == 4) break;}var_dump(current($arr));$arr1 = $arr;var_dump(current($arr));var_dump(current($arr1));?>

In demo2, we have commented out the if ($ value = 4) break; sentence. The goal is to use each to point the $ arr array pointer to the end of the array.

Result of demo2 execution: bool (false) int (1) bool (false ). If the element corresponding to the array pointer is 0, "", or is not a valid value, the current function returns false, and the $ arr value is not 0 or, therefore, it can be broken because the array pointer points to an invalid element, causing current to return a false value. In other words, after the while loop is completed, the $ arr array pointer has been directed to the end of the array. So we can see that the value of current ($ arr) before the value assignment is false, and the value of current ($ arr) after the value assignment is changed to 1, after the value is assigned, $ arr's array pointer is reset, pointing to the first element of the array. The value of current ($ arr1) is false, indicating that $ arr1 reserves the elements pointed to by the array pointer of $ arr before the value assignment.

Demo1 and demo2 can prove the above conclusion.

Therefore, in order not to be affected by the array pointer when traversing the array, it is best to call the reset () function before or after using the each () function to reset the array pointer. In this way, the above problems can be avoided. There is also a function prev () for operating the array pointer, which is used to move the current position of the array pointer back one bit, it also needs to pay attention, if the array pointer has already pointed to the end of the array, it will not get the expected result.

By the way, when the foreach function is used to traverse an array, it resets the array pointer and points it to the first element of the array. Note that the foreach operation object is the copy value of the array to be traversed, rather than the array itself.

...

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.