Antworten:
Es ist nach Wert gemäß der PHP-Dokumentation .
Standardmäßig werden Funktionsargumente als Wert übergeben (sodass der Wert des Arguments innerhalb der Funktion nicht außerhalb der Funktion geändert wird, wenn er geändert wird). Damit eine Funktion ihre Argumente ändern kann, müssen sie als Referenz übergeben werden.
Stellen Sie dem Argumentnamen in der Funktionsdefinition ein kaufmännisches Und ( & ) voran, damit ein Argument für eine Funktion immer als Referenz übergeben wird .
<?php
function add_some_extra(&$string)
{
$string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str; // outputs 'This is a string, and something extra.'
?>
$str = add_some_extra($str);
würde ich die Referenz nicht verwenden, oder? Was ist dann der wahre Mehrwert davon?
$str
in Ihrem Fall null zugewiesen wird.
In PHP werden Objekte standardmäßig als Referenzkopie an ein neues Objekt übergeben.
Siehe dieses Beispiel .............
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue($obj)
{
$obj->abc = 30;
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 30
Jetzt sehen Sie das ..............
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue($obj)
{
$obj = new Y();
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 10 not 20 same as java does.
Jetzt sehen Sie das ..............
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue(&$obj)
{
$obj = new Y();
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 20 not possible in java.
Ich hoffe du kannst das verstehen.
$y
wird nicht benötigt - es gibt nichts function changeValue
, was es erfordert, dass es sich im Inneren befindet class Y
, so dass zwei nicht miteinander verbundene Konzepte miteinander verwickelt werden. Ich würde function changeValue
zum äußeren Bereich übersteigen $x = new X();
. Entfernen Sie alle Verweise auf $y
. Jetzt ist es einfacher zu sehen, dass die ersten beiden Beispiele $ x in Ruhe lassen und das dritte seinen Inhalt in ändert new Y()
. Was leichter zu sehen wäre, wenn Sie das type
von $x
- die Tatsache, dass beide X
und Y
zufällig ein $abc
Feld enthalten, ist auch irrelevant für das, was demonstriert wird
Es scheint, dass viele Leute verwirrt sind, wie Objekte an Funktionen übergeben werden und was als Referenzmittel übergeben wird. Objektvariablen werden immer noch als Wert übergeben. Es ist nur der Wert, der in PHP5 übergeben wird, ein Referenzhandle. Als Beweis dafür:
<?php
class Holder {
private $value;
public function __construct($value) {
$this->value = $value;
}
public function getValue() {
return $this->value;
}
}
function swap($x, $y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
Ausgänge:
a, b
Um als Referenz zu übergeben , können wir die Variablen ändern, die vom Aufrufer gesehen werden. Was der obige Code eindeutig nicht tut. Wir müssen die Swap-Funktion ändern in:
<?php
function swap(&$x, &$y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
Ausgänge:
b, a
um als Referenz zu übergeben.
swap
Funktion übergeben würde. mit anderen Worten, wenn Objekte "als Wert übergeben" wurden. Andererseits ist es auch genau das, was Sie erwarten würden, wenn ein Objekthandle an die Funktion übergeben würde, was tatsächlich passiert. Ihr Code unterscheidet nicht zwischen diesen beiden Fällen.
http://www.php.net/manual/en/migration5.oop.php
In PHP 5 gibt es ein neues Objektmodell. Der Umgang von PHP mit Objekten wurde komplett neu geschrieben, um eine bessere Leistung und mehr Funktionen zu ermöglichen. In früheren Versionen von PHP wurden Objekte wie primitive Typen behandelt (z. B. Ganzzahlen und Zeichenfolgen). Der Nachteil dieser Methode war, dass semantisch das gesamte Objekt kopiert wurde, als eine Variable zugewiesen oder als Parameter an eine Methode übergeben wurde. Bei dem neuen Ansatz werden Objekte nach Handle und nicht nach Wert referenziert (man kann sich ein Handle als Objektkennung vorstellen).
PHP-Variablen werden nach Wert zugewiesen, nach Wert an Funktionen übergeben und beim Enthalten / Darstellen von Objekten als Referenz übergeben. Mit einem & können Sie das Übergeben von Variablen als Referenz erzwingen
Zugewiesen nach Wert / Referenzbeispiel:
$var1 = "test";
$var2 = $var1;
$var2 = "new test";
$var3 = &$var2;
$var3 = "final test";
print ("var1: $var1, var2: $var2, var3: $var3);
würde ausgeben
var1: Test, var2: Abschlusstest, var3: Abschlusstest
Übergeben von Wert / Referenz Exampe:
$var1 = "foo";
$var2 = "bar";
changeThem($var1, $var2);
print "var1: $var1, var2: $var2";
function changeThem($var1, &$var2){
$var1 = "FOO";
$var2 = "BAR";
}
würde ausgeben:
var1: foo, var2 BAR
Objektvariablen, die als Referenz übergeben werden exampe:
class Foo{
public $var1;
function __construct(){
$this->var1 = "foo";
}
public function printFoo(){
print $this->var1;
}
}
$foo = new Foo();
changeFoo($foo);
$foo->printFoo();
function changeFoo($foo){
$foo->var1 = "FOO";
}
Würde ausgeben:
FOO
(Das letzte Beispiel könnte wahrscheinlich besser sein ...)
$foo
ist ein Zeiger auf ein Objekt . $foo
wird als Wert an die Funktion übergeben changeFoo()
, da changeFoo()
ihr Parameter nicht mit a deklariert wurde &
.
Sie können eine Variable als Referenz an eine Funktion übergeben. Diese Funktion kann die ursprüngliche Variable ändern.
Sie können die Passage als Referenz in der Funktionsdefinition definieren:
<?php
function changeValue(&$var)
{
$var++;
}
$result=5;
changeValue($result);
echo $result; // $result is 6 here
?>
Sie können es so oder so machen.
Wenn Sie ein '&' Symbol voranstellen, wird die Variable, die Sie übergeben, ein und dieselbe wie ihr Ursprung. dh: Sie können als Referenz übergeben, anstatt eine Kopie davon zu erstellen.
so
$fred = 5;
$larry = & $fred;
$larry = 8;
echo $fred;//this will output 8, as larry and fred are now the same reference.
Variablen, die primitive Typen enthalten, werden in PHP5 als Wert übergeben. Variablen, die Objekte enthalten, werden als Referenz übergeben. Es gibt einen interessanten Artikel aus dem Linux Journal aus dem Jahr 2006, in dem dieser und andere OO-Unterschiede zwischen 4 und 5 erwähnt werden.
&
.
Objekte werden in PHP 5 als Referenz und in PHP 4 als Wert übergeben. Variablen werden standardmäßig als Wert übergeben!
Lesen Sie hier: http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html
&
.
&
vor den Parametern in der Definition definiert wurden. Wenn sie als Wert übergeben würden, würde das Objekt in dem Bereich, der die Funktion mit ihr als Parameter aufgerufen hat, dies tun nicht betroffen sein.
class Holder
{
private $value;
public function __construct( $value )
{
$this->value = $value;
}
public function getValue()
{
return $this->value;
}
public function setValue( $value )
{
return $this->value = $value;
}
}
class Swap
{
public function SwapObjects( Holder $x, Holder $y )
{
$tmp = $x;
$x = $y;
$y = $tmp;
}
public function SwapValues( Holder $x, Holder $y )
{
$tmp = $x->getValue();
$x->setValue($y->getValue());
$y->setValue($tmp);
}
}
$a1 = new Holder('a');
$b1 = new Holder('b');
$a2 = new Holder('a');
$b2 = new Holder('b');
Swap::SwapValues($a1, $b1);
Swap::SwapObjects($a2, $b2);
echo 'SwapValues: ' . $a2->getValue() . ", " . $b2->getValue() . "<br>";
echo 'SwapObjects: ' . $a1->getValue() . ", " . $b1->getValue() . "<br>";
Attribute können weiterhin geändert werden, wenn sie nicht als Referenz übergeben werden.
Ausgabe:
SwapObjects: b, a SwapValues: a, b
Für alle, die in Zukunft darauf stoßen, möchte ich dieses Juwel aus den PHP-Dokumenten teilen , die von einem anonymen Benutzer gepostet wurden :
Hier scheint es einige Verwirrung zu geben. Die Unterscheidung zwischen Zeigern und Referenzen ist nicht besonders hilfreich. Das Verhalten in einigen der bereits veröffentlichten "umfassenden" Beispiele kann in einfacheren, einheitlichen Begriffen erklärt werden. Hayleys Code zum Beispiel macht genau das, was Sie erwarten sollten. (Mit> = 5.3)
Erstes Prinzip: Ein Zeiger speichert eine Speicheradresse, um auf ein Objekt zuzugreifen. Jedes Mal, wenn ein Objekt zugewiesen wird, wird ein Zeiger generiert. (Ich habe mich noch nicht zu tief mit der Zend-Engine befasst, aber soweit ich sehen kann, gilt dies.)
2. Prinzip und Quelle der größten Verwirrung: Die Übergabe einer Variablen an eine Funktion erfolgt standardmäßig als Wertübergabe, dh Sie arbeiten mit einer Kopie. "Aber Objekte werden als Referenz übergeben!" Ein häufiges Missverständnis sowohl hier als auch in der Java-Welt. Ich habe nie eine Kopie von WAS gesagt. Die Standardübergabe erfolgt nach Wert. Immer. WAS jedoch kopiert und übergeben wird, ist der Zeiger. Wenn Sie "->" verwenden, greifen Sie natürlich auf dieselben Interna wie die ursprüngliche Variable in der Aufruferfunktion zu. Wenn Sie nur "=" verwenden, werden nur Kopien abgespielt.
3. Prinzip: "&" setzt automatisch und dauerhaft einen anderen Variablennamen / Zeiger auf dieselbe Speicheradresse wie etwas anderes, bis Sie sie entkoppeln. Es ist richtig, hier den Begriff "Alias" zu verwenden. Stellen Sie sich vor, Sie verbinden zwei Zeiger an der Hüfte, bis sie mit "unset ()" gewaltsam getrennt werden. Diese Funktionalität existiert sowohl im selben Bereich als auch wenn ein Argument an eine Funktion übergeben wird. Oft wird das übergebene Argument als "Referenz" bezeichnet, da in C und C ++ bestimmte Unterschiede zwischen "Übergeben nach Wert" und "Übergeben nach Referenz" deutlicher waren.
Denken Sie daran: Zeiger auf Objekte, nicht auf Objekte selbst, werden an Funktionen übergeben. Diese Zeiger sind KOPIEN des Originals, es sei denn, Sie verwenden "&" in Ihrer Parameterliste, um die Originale tatsächlich zu übergeben. Nur wenn Sie in die Interna eines Objekts graben, ändern sich die Originale.
Und hier ist das Beispiel, das sie liefern:
<?php
//The two are meant to be the same
$a = "Clark Kent"; //a==Clark Kent
$b = &$a; //The two will now share the same fate.
$b="Superman"; // $a=="Superman" too.
echo $a;
echo $a="Clark Kent"; // $b=="Clark Kent" too.
unset($b); // $b divorced from $a
$b="Bizarro";
echo $a; // $a=="Clark Kent" still, since $b is a free agent pointer now.
//The two are NOT meant to be the same.
$c="King";
$d="Pretender to the Throne";
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByValue($c, $d);
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByRef($c, $d);
echo $c."\n"; // $c=="Pretender to the Throne"
echo $d."\n"; // $d=="King"
function swapByValue($x, $y){
$temp=$x;
$x=$y;
$y=$temp;
//All this beautiful work will disappear
//because it was done on COPIES of pointers.
//The originals pointers still point as they did.
}
function swapByRef(&$x, &$y){
$temp=$x;
$x=$y;
$y=$temp;
//Note the parameter list: now we switched 'em REAL good.
}
?>
Ich habe einen ausführlichen Blog-Beitrag zu diesem Thema für JavaScript geschrieben , aber ich glaube, dass er für PHP, C ++ und jede andere Sprache gleichermaßen gut geeignet ist, in der die Leute verwirrt zu sein scheinen, ob es sich um eine Wertübergabe oder eine Referenzübergabe handelt.
Es ist klar, dass PHP wie C ++ eine Sprache ist, die die Referenzübergabe unterstützt. Standardmäßig werden Objekte als Wert übergeben. Wenn Sie mit Variablen arbeiten, in denen Objekte gespeichert sind, ist es hilfreich, diese Variablen als Zeiger zu betrachten (da dies auf Assemblyebene im Grunde genommen der Fall ist). Wenn Sie einen Zeiger als Wert übergeben, können Sie den Zeiger trotzdem "verfolgen" und die Eigenschaften des Objekts ändern, auf das verwiesen wird. Was Sie nicht tun können, ist, es auf ein anderes Objekt zeigen zu lassen. Nur wenn Sie einen Parameter explizit als Referenz übergeben deklarieren, können Sie dies tun.
Eigentlich sind beide Methoden gültig, aber es hängt von Ihren Anforderungen ab. Pass-Werte als Referenz machen Ihr Skript oft langsam. Es ist daher besser, Variablen nach Wert zu übergeben, indem der Ausführungszeitpunkt berücksichtigt wird. Außerdem ist der Codefluss konsistenter, wenn Sie Variablen nach Wert übergeben.
Verwenden Sie diese Option für Funktionen, wenn Sie die ursprüngliche Variable einfach ändern und sie wieder auf denselben Variablennamen mit dem neuen zugewiesenen Wert zurücksetzen möchten.
function add(&$var){ // The & is before the argument $var
$var++;
}
$a = 1;
$b = 10;
add($a);
echo "a is $a,";
add($b);
echo " a is $a, and b is $b"; // Note: $a and $b are NOT referenced
Abhängig von der Version ist 4 nach Wert, 5 nach Referenz.