PHP
referenser
Sök…
Syntax
-
$foo = 1; $bar = &$foo; // both $foo and $bar point to the same value: 1
-
$var = 1; function calc(&$var) { $var *= 15; } calc($var); echo $var;
Anmärkningar
När två variabler tilldelas genom referens pekar båda variablerna på samma värde. Ta följande exempel:
$foo = 1;
$bar = &$foo;
$foo
inte peka på $bar
. $foo
och $bar
båda pekar på samma värde på $foo
, som är 1
. Att illustrera:
$baz = &$bar;
unset($bar);
$baz++;
Om vi hade en points to
förhållande, skulle detta brytas nu efter unset()
; istället $baz
$foo
och $baz
fortfarande på samma värde, vilket är 2
.
Tilldela med referens
Detta är den första fasen av referenser. När du tilldelar en referens tillåter du två variabler att dela samma värde som sådant.
$foo = &$bar;
$foo
och $bar
är lika här. De behöver inte peka på varandra. De pekar på samma plats ( "värdet" ).
Du kan också tilldela genom referens inom språkkonstruktionen array()
. Samtidigt som det inte strikt är ett uppdrag som referens.
$foo = 'hi';
$bar = array(1, 2);
$array = array(&$foo, &$bar[0]);
Observera dock att referenser i matriser är potentiellt farliga. Att göra en normal (inte genom referens) tilldelning med en referens på höger sida gör inte vänster sida till en referens, men referenser inuti arrayer bevaras i dessa normala uppdrag. Detta gäller också för funktionssamtal där matrisen skickas efter värde.
Tilldelning genom referens är inte bara begränsad till variabler och matriser, de finns också för funktioner och alla "pass-by-reference" -associationer.
function incrementArray(&$arr) {
foreach ($arr as &$val) {
$val++;
}
}
function &getArray() {
static $arr = [1, 2, 3];
return $arr;
}
incrementArray(getArray());
var_dump(getArray()); // prints an array [2, 3, 4]
Tilldelning är nyckeln i funktionsdefinitionen enligt ovan. Du kan inte skicka ett uttryck genom referens, bara ett värde / variabel. Därför inställningen av $a
i bar()
.
Återvänd med referens
Ibland kommer det tid att implicit återvända-med-referens.
Återvändning med referens är användbart när du vill använda en funktion för att hitta till vilken variabel en referens ska binds. Använd inte retur-för-referens för att öka prestandan. Motorn optimerar detta automatiskt på egen hand. Returnera endast referenser när du har en giltig teknisk anledning till det.
Hämtad från PHP-dokumentationen för återvändande genom referens .
Det finns många olika former som returneras genom referens kan ta, inklusive följande exempel:
function parent(&$var) {
echo $var;
$var = "updated";
}
function &child() {
static $a = "test";
return $a;
}
parent(child()); // returns "test"
parent(child()); // returns "updated"
Återlämning med referens är inte bara begränsad till funktionsreferenser. Du kan också implicit kalla funktionen:
function &myFunction() {
static $a = 'foo';
return $a;
}
$bar = &myFunction();
$bar = "updated"
echo myFunction();
Du kan inte direkt referera till ett funktionssamtal, det måste tilldelas en variabel innan du utnyttjar det. För att se hur det fungerar, försök bara echo &myFunction();
.
anteckningar
- Du måste ange en referens (
&
) på båda platserna du tänker använda den. Det betyder för din funktionsdefinition (function &myFunction() {...
) och ifunction callFunction(&$variable) {...
eller&myFunction();
). - Du kan bara returnera en variabel genom referens. Därför instanseringen av
$a
i exemplet ovan. Detta betyder att du inte kan returnera ett uttryck, annars kommer ettE_NOTICE
PHP-fel att genereras (Notice: Only variable references should be returned by reference in ......
). - Återlämning med referens har legitima användningsfall, men jag bör varna för att de ska användas sparsamt, först efter att ha undersökt alla andra möjliga alternativ för att uppnå samma mål.
Gå förbi referens
Detta låter dig passera en variabel med hänvisning till en funktion eller element som gör att du kan ändra den ursprungliga variabeln.
Vidarebefordran är inte begränsad till endast variabler, följande kan också skickas genom referens:
- Nya uttalanden, t.ex.
foo(new SomeClass)
- Referenser returneras från funktioner
arrayer
En vanlig användning av "förbipasserande-referens" är att ändra initialvärden inom en matris utan att gå till omfattningen av att skapa nya matriser eller kasta ditt namnområde. Att lämna-genom-referens är lika enkelt som att föregå / prefixera variabeln med en &
=> &$myElement
.
Nedan visas ett exempel på att utnyttja ett element från en matris och helt enkelt lägga till 1 till dess initialvärde.
$arr = array(1, 2, 3, 4, 5);
foreach($arr as &$num) {
$num++;
}
När du utnyttjar ett element inom $arr
kommer det ursprungliga elementet att uppdateras när referensen ökades. Du kan verifiera detta genom att:
print_r($arr);
Notera
Du bör ta hänsyn till när du utnyttjar pass genom referens inom öglor. I slutet av ovanstående slinga har
$num
fortfarande en referens till det sista elementet i matrisen. Att tilldela den efter slingan kommer att manipulera det sista arrayelementet! Du kan säkerställa att detta inte händer genom attunset()
"in the post-loop:$myArray = array(1, 2, 3, 4, 5); foreach($myArray as &$num) { $num++; } unset($num);
Ovanstående säkerställer att du inte stöter på några problem. Ett exempel på frågor som kan relatera till detta finns i denna fråga på StackOverflow .
funktioner
En annan vanlig användning för förbipasserande är inom funktioner. Att ändra den ursprungliga variabeln är så enkelt som:
$var = 5;
// define
function add(&$var) {
$var++;
}
// call
add($var);
Vilket kan verifieras genom att echo
'den ursprungliga variabeln.
echo $var;
Det finns olika begränsningar kring funktioner, som anges nedan från PHP-dokumenten:
Obs: Det finns inget referensmärke på ett funktionssamtal - bara för funktionsdefinitioner. Funktionsdefinitioner enbart räcker för att korrekt skicka argumentet genom referens. Från PHP 5.3.0 får du en varning som säger att "pass-by-referens" för samtalstid avskrivs när du använder & in foo (& $ a); Och från och med PHP 5.4.0 togs bort pass-by-referens för samtalstid, så att använda det kommer att leda till ett dödligt fel.