Php reference (& amp;) explanation and precautions _ PHP Tutorial

Source: Internet
Author: User
Tags php example
Php reference (& amp;) details and precautions. Php references (that is, adding symbols before variables, functions, and objects) in PHP mean that different names access the same variable content. The pointer in C language is referenced by php (that is, it is added with the & symbol before the variable, function, object, and so on)

The reference in PHP means that different names access the same variable content.
The pointer is different from the pointer in C language. the pointer in C language stores the variable content and the address stored in memory.

1. variable reference

PHP reference allows you to use two variables to point to the same content

$ A = "ABC ";
$ B = & $;
Echo $ a; // output here: ABC
Echo $ B; // output here: ABC
$ B = "EFG ";
Echo $ a; // Here, the value of $ a is changed to EFG, So EFG is output.
Echo $ B; // output EFG here
?>


2. function reference transfer (address transfer)


I will not talk much about the address transfer call. the following code is provided directly.

Function test (& $)
{
$ A = $ a + 100;
}
$ B = 1;
Echo $ B; // output 1
Test ($ B); // here, $ B actually transmits the memory address of the variable content of $ B to the function, you can change the value of $ B by changing the value of $ a in the function.
Echo"
";
Echo $ B; // output 101
?>

Note that test (1); will cause an error.

Note:

In the above "test ($ B);", do not add the & symbol before $ B, but in the function "call_user_func_array", to reference the parameter passing, you need the & symbol, the following code is used:

Function a (& $ B ){
$ B ++;
}
$ C = 0;

Call_user_func_array ('A', array (& $ c ));

Echo $ c;

// Output 1

?>


3. function reference return


First look at the code

Function & test ()
{
Static $ B = 0; // declare a static variable
$ B = $ B + 1;
Echo $ B;
Return $ B;
}

$ A = test (); // This statement outputs the value of $ B as 1.
$ A = 5;
$ A = test (); // This statement outputs the value of $ B to 2.

$ A = & test (); // This statement outputs the value of $ B to 3.
$ A = 5;
$ A = test (); // This statement outputs a value of 6 for $ B.
?>

The following explains:
In this way, $ a = test (); is not actually returned by the function reference, which is no different from the normal function call. The reason is: this is the PHP rule.
PHP requires that $ a = & test (); is used to obtain the function reference and return.
As for what is reference return (in the PHP Manual, reference return is used when you want to use a function to find the variable on which the reference should be bound .) I haven't understood this sentence for a long time.

The example above is as follows:
$ A = test () is used to call a function. it only assigns the value of the function to $ a. any change made to $ a does not affect $ B in the function.
But how to call a function through $ a = & test, the function is to direct the memory address of the $ B variable in return $ B to the same place as the memory address of the $ a variable.
That is, the equivalent effect ($ a = & $ B;) is generated. Therefore, changing the value of $ a also changes the value of $ B.
$ A = & test ();
$ A = 5;
Later, the value of $ B is changed to 5.

Static variables are used to help you understand the reference and return functions. In fact, function reference and return are mostly used in objects.


Another official php example is provided:

This is the way how we use pointer to access variable inside the class.

Class talker {

Private $ data = 'hi ';

Public function & get (){
Return $ this-> data;
}

Public function out (){
Echo $ this-> data;
}

}

$ Aa = new talker ();
$ D = & $ aa-> get ();

$ Aa-> out ();
$ D = 'who ';
$ Aa-> out ();
$ D = 'all ';
$ Aa-> out ();
$ D = 'you ';
$ Aa-> out ();
?>

The output is "HiHowAreYou"

4. object reference


Class {
Var $ abc = "ABC ";
}
$ B = new;
$ C = $ B;
Echo $ B-> abc; // output ABC here
Echo $ c-> abc; // output ABC here
$ B-> abc = "DEF ";
Echo $ c-> abc; // output DEF here
?>

The above code is the running effect in PHP5

In PHP5, object assignment is a reference process. In the above column, $ B = new a; $ c = $ B; is equivalent to $ B = new a; $ c = & $ B;
In PHP5, the object is called by reference by default, but sometimes you may want to create a copy of the object and expect that the change of the original object will not affect the copy. for this purpose, PHP5 defines a special method called _ clone.

Since PHP 5, new automatically returns a reference. Therefore, when = & is used here, messages at the E_STRICT level will be generated.

In php4, the value assignment of an object is a copy process,

For example, $ B = new a, where new a generates an anonymous a object instance, and $ B copies the anonymous object. Similarly, $ c = $ B is a copy of $ B content. Therefore, in php4, to save memory space, $ B = new a is generally changed to the reference mode, that is, $ B = & new.

The following is an official example:

In php5, you can get the "object reference" function without adding anything else:

Class foo {
Protected $ name;
Function _ construct ($ str ){
$ This-> name = $ str;
}
Function _ toString (){
Return 'My name is "'. $ this-> name.'" and I live in "'. _ CLASS _.'". '. "\ n ";
}
Function setName ($ str ){
$ This-> name = $ str;
}
}

Class MasterOne {
Protected $ foo;
Function _ construct ($ f ){
$ This-> foo = $ f;
}
Function _ toString (){
Return 'master: '. _ CLASS _.' | foo: '. $ this-> foo. "\ n ";
}
Function setFooName ($ str ){
$ This-> foo-> setName ($ str );
}
}

Class MasterTwo {
Protected $ foo;
Function _ construct ($ f ){
$ This-> foo = $ f;
}
Function _ toString (){
Return 'master: '. _ CLASS _.' | foo: '. $ this-> foo. "\ n ";
}
Function setFooName ($ str ){
$ This-> foo-> setName ($ str );
}
}

$ Bar = new foo ('bar ');

Print ("\ n ");
Print ("Only Created \ $ bar and printing \ $ bar \ n ");
Print ($ bar );

Print ("\ n ");
Print ("Now \ $ baz is referenced to \ $ bar and printing \ $ bar and \ $ baz \ n ");
$ Baz = & $ bar;
Print ($ bar );

Print ("\ n ");
Print ("Now Creating MasterOne and Two and passing \ $ bar to both constructors \ n ");
$ M1 = new MasterOne ($ bar );
$ M2 = new MasterTwo ($ bar );
Print ($ m1 );
Print ($ m2 );

Print ("\ n ");
Print ("Now changing value of \ $ bar and printing \ $ bar and \ $ baz \ n ");
$ Bar-> setName ('Baz ');
Print ($ bar );
Print ($ baz );

Print ("\ n ");
Print ("Now printing again MasterOne and Two \ n ");
Print ($ m1 );
Print ($ m2 );

Print ("\ n ");
Print ("Now changing MasterTwo's foo name and printing again MasterOne and Two \ n ");
$ M2-> setFooName ('mastertwo \'s Foo ');
Print ($ m1 );
Print ($ m2 );

Print ("Also printing \ $ bar and \ $ baz \ n ");
Print ($ bar );
Print ($ baz );
?>

Output:

Only Created $ bar and printing $ bar
My name is "bar" and I live in "foo ".

Now $ baz is referenced to $ bar and printing $ bar and $ baz
My name is "bar" and I live in "foo ".

Now Creating MasterOne and Two and passing $ bar to both constructors
Master: MasterOne | foo: my name is "bar" and I live in "foo ".

Master: MasterTwo | foo: my name is "bar" and I live in "foo ".

Now changing value of $ bar and printing $ bar and $ baz
My name is "baz" and I live in "foo ".
My name is "baz" and I live in "foo ".

Now printing again MasterOne and Two
Master: MasterOne | foo: my name is "baz" and I live in "foo ".

Master: MasterTwo | foo: my name is "baz" and I live in "foo ".

Now changing MasterTwo's foo name and printing again MasterOne and Two
Master: MasterOne | foo: my name is "MasterTwo's Foo" and I live in "foo ".

Master: MasterTwo | foo: my name is "MasterTwo's Foo" and I live in "foo ".

Also printing $ bar and $ baz
My name is "MasterTwo's Foo" and I live in "foo ".
My name is "MasterTwo's Foo" and I live in "foo ".

Analysis of the previous example:

$ Bar = new foo ('bar ');
$ M1 = new MasterOne ($ bar );
$ M2 = new MasterTwo ($ bar );

The $ bar in the instance object $ m1 and $ m2 is a reference to the instance $ bar instead of a copy. this is a feature of object reference in php5, that is
1. Inside $ m1 or $ m2, any operation on $ bar will affect the value of $ bar of the external object instance.
2. changes to the external object instance $ bar also affect the reference values of $ m1 and $ m2.

In php4, the equivalent code (that is, reference and call) is similar to the preceding example when an object instance is used as an attribute of another object:

Class foo {
Var $ bar;
Function setBar (& $ newBar ){
$ This-> bar = & newBar;
}
}

5. Role of reference
If the program is large, there are many variables that reference the same object, and you want to manually clear the object after it is used up, I suggest using the & method, then clear it in the form of $ var = null. in other cases, use the default php5 method. in addition, we recommend that you use the "&" method for transferring large arrays in php5 to save memory space.


6. cancel the reference.
When you unset a reference, you just disconnect the binding between the variable name and the variable content. This does not mean that the variable content is destroyed. For example:


$ A = 1;
$ B = & $;
Unset ($ );
?>


Not unset $ B, just $.


7. global reference
When a variable is declared with global $ var, a reference to the global variable is actually created. That is to say, it is the same as doing so:

$ Var = & $ GLOBALS ["var"];
?>

This means that, for example, unset $ var does not unset global variables.


If a global variable is assigned to a reference within a function, the reference is only visible within the function. You can avoid this by using the $ GLOBALS array.

Example reference the global variable www.2cto.com in the function

$ Var1 = "Example variable ";
$ Var2 = "";

Function global_references ($ use_globals)
{
Global $ var1, $ var2;
If (! $ Use_globals ){
$ Var2 = & $ var1; // visible only inside the function
} Else {
$ GLOBALS ["var2"] = & $ var1; // visible also in global context
}
}

Global_references (false );
Echo "var2 is set to '$ var2' \ n"; // var2 is set''
Global_references (true );
Echo "var2 is set to '$ var2' \ n"; // var2 is set to 'example variable'
?>

Use global $ var as the abbreviation of $ var = & $ GLOBALS ['var. Therefore, assigning other references to $ var only changes the reference of local variables.


8. $ this
In the method of an object, $ this is always a reference to the object that calls it.


// Next is an episode
In php, the address pointing (similar to pointer) function is not implemented by the user, but is implemented by the Zend core. in php, the reference uses the principle of "copy at Write, unless a write operation occurs, the variables or objects pointing to the same address will not be copied.

In layman's terms
1: if the following code exists:

$ A = "ABC ";
$ B = & $;
?>

In fact, both $ a and $ B point to the same memory address, not $ a and $ B occupy different memory.

2: Add the following code on the basis of the above code:

$ A = "EFG ";
?>

Because the memory data pointed to by $ a and $ B needs to be re-written, the Zend core automatically determines that $ B will generate a $ a data copy, apply for a new memory for storage


Php reference (that is, adding & symbol before variables, functions, and objects) is an advanced topic. it is important for new users to pay more attention to correct understanding of php references, it has a great impact on performance, and understanding errors may lead to program errors!

Many people misunderstand that the reference in php is the same as the pointer in C. in fact, this is not the case and it is quite different. In C language, pointers do not need to be explicitly declared in the array transfer process, but must be fixed using *. in php, pointers to addresses (similar to pointers) the function is not implemented by the user, but by the Zend core. the reference in php adopts the principle of "copy at Write Time", that is, unless a write operation occurs, variables or objects pointing to the same address are not copied, for example, the following code:

$ A = array ('A', 'C'... 'n ');
$ B = $;

If the program is only executed here, $ a and $ B are the same, but not like C, $ a and $ B occupy different memory space, it points to the same memory, which is the difference between php and c. it does not need to be written as $ B = & $ a to indicate that $ B points to $ a memory, zend has already helped you implement the reference, and zend will be very intelligent to help you determine when to handle this, and when not to handle this.

If you continue to write the following code later, add a function, pass parameters by referencing, and print the output array size.

Function printArray (& $ arr) // reference transfer
{
Print (count ($ arr ));

}
PrintArray ($ );

In the above code, we pass the $ a array into the printArray () function through reference. the zend Engine will think that printArray () may cause changes to $, at this time, a $ a data copy is automatically generated for $ B, and a memory is re-applied for storage. This is the "copy at write time" concept mentioned above.

If we change the above code to the following:

Function printArray ($ arr) // value transfer
{
Print (count ($ arr ));
}
PrintArray ($ );

The above code directly transmits the $ a value to printArray (). at this time, there is no reference transfer, so there is no copy at write time.

You can test the execution efficiency of the above two lines of code, for example, adding a loop 1000 times outside to check the running time, the result will let you know that improper use of the reference will lead to a performance reduction of more than 30%.

Self-understanding: values are irrelevant to parameters in the function, which is equivalent to local variables, while values are related to parameters in the function by reference, it is equivalent to a global variable. in terms of performance, the above analysis is sufficient ..


Reference
PHP references allow two variables to point to the same content. This means that when you do this:

$ A = & $ B;
?>
This means that $ a and $ B point to the same variable.
Note:

$ A and $ B are exactly the same here. this doesn't mean $ a points to $ B or vice versa, but $ a and $ B point to the same place.

Note:

If an array with a reference is copied, its value is not removed from the reference. This is also true for passing values from arrays to functions.

Note:

If an undefined variable is referenced, assigned, referenced, or returned, the variable is automatically created.

Example #1 use reference for undefined variables

Function foo (& $ var ){}

Foo ($ a); // $ a is "created" and assigned to null

$ B = array ();
Foo ($ B ['B']);
Var_dump (array_key_exists ('B', $ B); // bool (true)

$ C = new StdClass;
Foo ($ c-> d );
Var_dump (property_exists ($ c, 'D'); // bool (true)
?>
The same syntax can be used in functions, which return references, and in the new operator (PHP 4.0.4 and later versions ):

$ Bar = & new fooclass ();
$ Foo = & find_var ($ bar );
?>
Since PHP 5, new automatically returns a reference. Therefore, when = & is used here, messages at the E_STRICT level will be generated.
Note:

No & operator is used to generate a copy of the object. If $ this is used in the class, it will act on the current instance of the class. The instance (such as an object) will be copied without a value & and $ this will apply to this copy, which is not always the desired result. Due to performance and memory consumption problems, you usually only want to work on one instance.

Although the @ operator can be used to suppress any error information in the constructor, such as @ new, it does not work when the & new statement is used. This is a limitation of the Zend Engine and may cause a parsing error.

Warning
If a global variable is assigned to a reference within a function, the reference is only visible within the function. You can avoid this by using the $ GLOBALS array.

Example #2 reference global variables in the function

$ Var1 = "Example variable ";
$ Var2 = "";

Function global_references ($ use_globals)
{
Global $ var1, $ var2;
If (! $ Use_globals ){
$ Var2 = & $ var1; // visible only inside the function
} Else {
$ GLOBALS ["var2"] = & $ var1; // visible also in global context
}
}

Global_references (false );
Echo "var2 is set to '$ var2' \ n"; // var2 is set''
Global_references (true );
Echo "var2 is set to '$ var2' \ n"; // var2 is set to 'example variable'
?>
Use global $ var as the abbreviation of $ var = & $ GLOBALS ['var. Therefore, assigning other references to $ var only changes the reference of local variables.
Note:

If you assign a value to a referenced variable in the foreach statement, the referenced object is also changed.

Example #3 references and foreach statements

$ Ref = 0;
$ Row = & $ ref;
Foreach (array (1, 2, 3) as $ row ){
// Do something
}
Echo $ ref; // 3-last element of the iterated array
?>
The second thing to do with referencing is to use referencing to pass variables. This is achieved by creating a local variable in the function and referencing the same content in the call range. For example:

Function foo (& $ var)
{
$ Var ++;
}

$ A = 5;
Foo ($ );
?>
Changes $ a to 6. This is because the variable $ var points to the same content as $ a in the foo function. For more detailed explanations, refer to transfer references.
The third thing to reference is to reference and return

Array reference bug (it was not a bug after careful consideration)


It appears that references can have side-effects. below are two examples. both are simply copying one array to another. in the second example, a reference is made to a value in the first array before the copy. in the first example the value at index 0 points to two separate memory locations. in the second example, the value at index 0 points to the same memory location.

I won't say this is a bug, because I don't know what the designed behavior of PHP is, but I don't think ANY developers wowould perform CT this behavior, so look out.

An example of where this cocould cause problems is if you do an array copy in a script and perform CT on type of behavior, but then later add a reference to a value in the array earlier in the script, and then find that the array copy behavior has unexpectedly changed.

// Example one
$ Arr1 = array (1 );
Echo "\ nbefore: \ n ";
Echo "\ $ arr1 [0] =={$ arr1 [0]} \ n ";
$ Arr2 = $ arr1;
$ Arr2 [0] ++;
Echo "\ nafter: \ n ";
Echo "\ $ arr1 [0] =={$ arr1 [0]} \ n ";
Echo "\ $ arr2 [0] =={$ arr2 [0]} \ n ";


Output:

Before:
$ Arr1 [0] = 1

After:
$ Arr1 [0] = 1
$ Arr2 [0] = 2

// Example two

$ Arr3 = array (1 );
$ A = & $ arr3 [0];
Echo "\ nbefore: \ n ";
Echo "\ $ a = $ a \ n ";
Echo "\ $ arr3 [0] =={$ arr3 [0]} \ n ";
$ Arr4 = $ arr3;
$ Arr4 [0] ++;
Echo "\ nafter: \ n ";
Echo "\ $ a = $ a \ n ";
Echo "\ $ arr3 [0] =={$ arr3 [0]} \ n ";
Echo "\ $ arr4 [0] =={$ arr4 [0]} \ n ";


Output:

Before:
$ A = 1
$ Arr3 [0] = 1

After:
$ A = 2
$ Arr3 [0] = 2
$ Arr4 [0] = 2

?>



Analysis description:

For "Example two", I thought it was a bug at the beginning. In fact, I did not think it was a bug. the analysis is as follows,

Assign a value (copy)

$ Arr4 = $ arr3;

Previously, there was another process of creating a reference to the first element of $ arr3, that is

$ A = & $ arr3 [0];

Therefore, in the subsequent value copy ($ arr4 = $ arr3;), the reference will be copied together.

$ A, $ arr3 [0], and $ arr4 [0] are actually reference relations, pointing to the same place.

From PPP

Using (adding a symbol before a variable, function, or object) in PHP means that different names access the same variable content. And pointers in C language are...

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.