In the past, the reference in PHP has always been mysterious. It is different from the reference in C #. However, it is rarely used, or is hard to come into use, so the understanding of the reference in PHP has always been a point of thumb, and I have not studied it in depth. It is because of this that there is always a sense of reverence. today, when I wrote a PHP script, I found
In the past, the reference in PHP has always been mysterious. It is different from the reference in C #. However, it is rarely used, or is hard to come into use, so the understanding of the reference in PHP has always been a point of thumb, and I have not studied it in depth. It is because of this that there is always a sense of reverence. today, when I wrote a PHP script, I found
In the past, the reference in PHP has always been mysterious. It is different from the reference in C #. However, it is rarely used, or is hard to come into use, so the understanding of the reference in PHP has always been a point of thumb, and I have not studied it in depth. It is because of this that there is always a sense of reverence. today, when I wrote a PHP script, I found a reference problem. It took me half a day to solve it, but this problem made me not start to face up to the reference in PHP, and how to understand and use references.
The cause of the problem is the following code:
1 class
2 {
3 public $ classb;
4 public $ arr = array ();
5
6 public function _ construct () {$ this-> classb = new B ();}
7 /**
8 * @ return B
9 */
10 public function getB () {return $ this-> classb ;}
11 /**
12 *
13 * @ return array
14 */
15 public function getArray () {return $ this-> arr ;}
16 public function _ clone () {$ this-> classb = clone $ this-> classb ;}
17}
18 class B
19 {
20 public $;
21 public $ B;
22 public function _ construct ()
23 {
24 $ this-> a = '';
25 $ this-> B = 0;
26}
27 public function _ toString () {return $ this-> a. $ this-> B ;}
28}
29
30 $ a = new ();
31 $ B = $ a-> getB ();
32 $ B-> a = 'abc ';
33 $ B-> B = 3;
34 $ arr = $ a-> getArray ();
35 $ arr [0] = 'a ';
36 $ arr [1] = 'B ';
37 var_dump ($ );
The execution result is that the value of $ a-> classb has changed, but the value of $ a-> arr has not changed, that is, a reference returned by getB, all the changes above are equivalent to directly acting on the member variables of the class, while the getArray method returns only a copy, that is, passing by value; but before getArray, and add & before the $ this-> getArray to indicate that the return result is referenced. The value of $ a-arr is changed. If I want the getB method to do the same, the effect is the same as when no & is added. if the same method declaration method and the same call method are used, why is one returned by reference by default (getB), and the other passed by value? After carefully comparing the types of the classb and arr variables, we found that one is my own defined class and the other is the original array type. will all primitive types be passed by value by default, and all non-primitive types (such as classes and interfaces) are passed by reference. with this question, I tested several primitive types, such as int, string, and bool, and redefined several classes. The methods used include function return values and parameter declarations, function parameters and so on. The test result is as I guess.
Combined. NET and JAVA type transfer methods I found that the type transfer methods in PHP are exactly the same, class types are passed by reference, the only difference is that in PHP, the array is passed as a value type, and. the array in net is a reference type, which is why I have some doubts about the results of the previous code. I don't know what articles I have seen that PHP is a pass by reference. Now it seems that this sentence is not completely correct, all the class types should be pass by reference, and all the value types pass by value (different from C #, the string should also be considered as a value type here, although the strings in C # are also passed by value by default ).
Let's look back at the PHP manual. Here we mention an objective sentence. From PHP 5, new automatically returns a reference, that is, all objects instantiated with new get references, what will be instantiated using new? It can only be of the class type. in this case, what I mentioned above should be correct. maybe I'm not careful enough. I didn't see a specific conclusion in all the chapters of the manual. If you know something, please tell your younger brother.
After figuring out this problem, we don't have to worry about how to return Members when facing the object-oriented design and programming in PHP again. We should not display the addition or not &, this parameter should not be used during parameter declaration &. after using C # For a long time, I always like to use C # as an analogy. This time is no exception. we know that when we declare parameters in C #, we can use 'ref ', 'out', and so on to modify the parameters. In the 'out' mode, Let's ignore it. Let alone this 'ref '. let's take a look at two examples.
1 class PHPClass
2 {
3 public static function TestRef (& $)
4 {
5 $ B = $;
6 $ a = $ a + 1;
7 return $ B;
8}
9 public static function TestRef2 (& $ B)
10 {
11 $ B = new B ();
12}
13}
14 $ a = 1;
15 $ aa = $;
16 $ result = PHPClass: TestRef ($ aa );
17 $ B = new B ();
18 $ bb = $ B;
19 PHPClass: TestRef2 ($ bb );
1 public static class CSharpClass
2 {
3 public static void TestRef (ref int)
4 {
5 int B =;
6 a = a + 1;
7 return B;
8}
9 public static void TestRef2 (ref B)
10 {
11 B = new B ();
12}
13}
14 int a = 1;
15 int aa =;
16 int result = CSharClass. TestRef (ref aa );
17 B B = new B ();
18 B bb = B;
19 CSharClass. TestRef (ref bb );
This is the PHP and C # implementations of the same function. After each execution, will a, aa, B, and bb be implemented?
In PHP, $ a = $ aa is false, $ B = $ bb is true, and a = aa is false in C, B = bb is also false. the first value is an integer value assignment, and the result of passing the reference is basically the same as I imagined. However, the next group uses the class type assignment to pass the reference result, which is too confusing. it turns out that this "Reference" is not "Reference. although the default class type in PHP is pass by reference, it seems like the class type in PHP, all the references derived from the same object are tied to the same reference value pointing to the real object (imagine a pointer), or connected to the same umbilical cord, the object to which a reference is directed is changed, and all the objects to which the reference is directed are changed. This is different from what we understand when doing C # programs. the reference variable in C # is more like an independent value irrelevant to other references. One of them is changed to point to a new object, and the rest will not change. therefore, it is easy to think that if you change the above $ aa = $ a; sentence to $ aa = & $ a; then the $ a = $ aa in the result will become true.
Let's look at a more confusing code:
1 function getColor ($ k)
2 {
3 // default return value
4 $ color = 'red ';
5 $ value = & $ color;
6
7 $ arr = array (1: 'red', 2: 'green', 3: 'blue ');
8 foreach ($ arr as $ key => $ value)
9 {
10 // do something
11 if ($ k = $ key)
12 {
13 $ color = $ value;
14 break;
15}
16}
17 return $ color;
18}
19
This is a way to obtain the color. I originally wanted to obtain the corresponding color based on the given key. If there is no color, the default value red is returned, but the running result is to find the given value, the returned value is correct. When the given value cannot be found, blue is always returned but not the red we want. The key point is $ value = & $ color, it is equivalent to binding $ value and $ color to a reference value. In the foreach loop, every change of $ value is equivalent to every change of $ color, so when the key value of the phase is not found, $ value is the last value in the array, that is, blue, therefore, the color value becomes blue instead of the default red. At the same time, we can see that the $ color = $ value in the middle of the loop is redundant, because $ color is always equal to $ value.
It seems that the Reference in PHP is not a simple "Pass By Reference" that can be summarized. When using it, you need to be especially careful to avoid errors. I suggest you try not to use it when you don't need it. Otherwise, you don't know where your variables are referenced, and you accidentally changed the value. Then, debugging will be very painful. if it is used up, call unset to cancel the reference (it is also a concept with the same name but different meanings in other languages), and cut the relationship between the umbilical cord and the referenced object.