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 i function 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 ett E_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 att unset() "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.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow