Home  >  Article  >  Backend Development  >  Analysis of citation reasons for using PHP with caution_PHP Tutorial

Analysis of citation reasons for using PHP with caution_PHP Tutorial

WBOY
WBOYOriginal
2016-07-21 15:16:41710browse

Reference types are used in many computer languages ​​and exist as a very powerful and practical feature. It has an implementation similar to a pointer, but behaves differently from a pointer. For example, C++ references can allow different variables to point to the same object, while maintaining the direct use of dot to obtain object members, without the cumbersome use of dereference operator (*) and Pointer to Member operator (->). In Java and C#, references are directly used as the main type, and developers try to avoid using pointers.

Reference types have also been introduced in PHP. In terms of object assignment and transfer, it can basically be regarded as the same reference transfer as Java/C# (see Objects and references for details). But at the same time, it supports obtaining a reference to the content through the reference operator (&) on the basic type. However, in actual use, PHP's reference type has many problems due to the entire PHP design structure, causing unexpected results in the program.


Reference variables can be assigned new references

In C++, a reference type variable can only be assigned a reference value when it is defined, so we As long as you trace the definition of the variable, you can know what the variable is operating on.

But PHP is different. The definition of variables is blurred in PHP, and variables can be used without defining them. So a variable can be assigned a reference value multiple times.

Copy code The code is as follows:

$x = 21;
$y = 7;

$z = &$x;
$z = &$y;

var_dump($x,$y,$z);

At first glance, let The human feeling is that $z becomes a reference to $x, and then the content of $z becomes a reference to $y. That is to say, both $x and $z become references to $y. But the actual output result is:
Copy code The code is as follows:

int(21)
int(7)
int(7)

From the result, $x remains unchanged, but $z is changed to a reference to $y. It is equivalent to unsetting the $z variable first and then assigning a new value.
Copy code The code is as follows:

$z = &$x;
unset($z);
$z = &$y;

This is actually more reasonable logic. For example, in the code below, we do not get something like "Pointer point to a Pointer" The "Reference refer to a Reference" is just a reference variable that refers to the same piece of content.
Copy code The code is as follows:

$x = 21;
$y = &$x;
$z = &$y


Referring to an array element will make the element a reference type

For variable reference, it will not This causes the original variable type to change, but if the element in the array is taken, the element will also become a reference type.

Before looking at the question code, the first thing to point out is:
Array assignment always involves value copying. Use the reference operator to copy an array by reference.

That is to say, PHP Array assignment is a copy rather than a reference. The assignment process will create a new array and assign it to the assigned variable. Array operations on the new variable will not affect the contents of the original array variable.
Copy code The code is as follows:

$a = array(21, 7);
$b = $a ;
$b[0] = 7;
var_dump($a);
echo '
';
var_dump($b);

/ /Output:
//array(2) { [0]=> int(21) [1]=> int(7) }
//array(2) { [0]=> int(7) [1]=> int(7) }

Let’s take a look at what exceptions will occur if we reference elements in the array.
Copy code The code is as follows:

$a = array(21, 7);
$c = & $ a[0];
$b = $a;
$b[0]= "21";
$b[1]= "7";

var_dump($a );
echo '
';
var_dump($b);
echo '
';
var_dump($c);
echo '
';

// Output:
// array(2) { [0]=> &string(2) "21" [1]=> int( 7) }
// array(2) { [0]=> &string(2) "21" [1]=> string(1) "7" }
// string(2) " 21"

$b in the code is just a simple assignment, except that there is an extra reference to get the first element, but it should still copy a new array. But the result is a modification of $b, which also changes the first element of $a, while the second element has no effect.

We also see an unusual thing from the output, that is, the type of the first element of the array has an extra '&' symbol. And this is exactly the reference operator. That is to say, the first element of the array has become a reference type. Therefore, assignment is also a reference copy, not a value copy.

This problem is very strange, and it also caused a lot of unnecessary trouble during development. I originally thought that the copied array was not related to the original array, but because of this unexpected reference type, I was confused during the operation. The original array is affected.

I don’t know if this is a bug in PHP or if it is intentionally designed this way. I have been searching online for a long time but there is no relevant explanation for this convenience. Only Float Middle's "PHP: References To Array Elements Are Risky" and Symmetric Designs' "Problems w/accessing a PHP array by reference" talk about this, but No reason was given.

Later, I saw several related reports (Bug6417, Bug7412, Bug15025, Bug20993) in the PHP Bug Report. Some say this is a bug and has been fixed in later versions. I don't understand the specifics, I can only avoid using references on arrays.

The more interesting thing is that if you unset those references and leave only one, then the array elements will become normal types without references.

Copy code The code is as follows:

unset($b);
unset($c);
var_dump($a);

// Output:
//array(2) { [0]=> string(2) "21" [1]=> int( 7) }


Avoid using PHP references

This is actually something to pay attention to mentioned in the PHP Array Manual. It most often occurs in foreach, where you hope to change the value of the far array through a reference (see this article).

In fact, I want to change the value of the array element by using foreach with references, mainly because PHP's array is an Associative Array. This kind of array has "indefinite length, the index can be discontinuous, and strings and integers can be used as indexes at the same time." So we cannot simply increment the integer index using a for loop.

Of course we can directly change the value of the array element through $key like the code below, but this may have certain efficiency issues.

Copy code The code is as follows:

foreach ($array_var as $key => $value)
$array_var [$key] = $newValue;

Another common place for references is to pass parameters by reference in function calls. The main reason is to use this method to allow the function to return multiple return values. For example, we want to use a representation to indicate whether an error occurs during execution of the function and the return value is invalid.

But because PHP functions can return different types, there is no need to pass in reference parameters as representation. Even if you really need multiple return values, you can still return an "array with a string as the primary key" as a solution, but you may need to point out in the documentation that each element corresponds to that result.

A better way to operate it is to use unset on the variable immediately to switch the connection with the content whenever the referenced variable no longer needs to be used. And even if the variable is not a reference type, we confirm that it is no longer used , and there will be no problem calling unset on it. At least it is guaranteed that reassigning the variable later will not affect the previous result.

    Problems w/accessing a PHP array by reference - Symmetric Designs
  1. PHP: References To Array Elements Are Risky – Float Middle
  2. References and foreach - Johannes Schlüter
  3. References Explained - PHP Manual

http://www.bkjia.com/PHPjc/325843.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/325843.htmlTechArticleReference type (Reference) is used in many computer languages ​​and is a very powerful and practical feature exist. It has an implementation similar to pointer, but is different from...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn