PHP 変数は値によって渡されますか?それとも参照によって渡されますか?
-
08-06-2019 - |
質問
PHP 変数は値渡しですか、それとも参照渡しですか?
解決
それは値によるものです PHP ドキュメント.
デフォルトでは、関数の引数は値によって渡されます (そのため、関数内の引数の値が変更されても、関数の外部では変更されません)。関数がその引数を変更できるようにするには、引数を参照によって渡す必要があります。
関数への引数を常に参照渡しするには、先頭にアンパサンド (&) を関数定義の引数名に追加します。
<?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.'
?>
他のヒント
オブジェクトを関数に渡す方法と参照渡しの意味について混乱している人が多いようです。オブジェクト変数は依然として値によって渡されます。PHP5 で渡される値は参照ハンドルです。証拠として:
<?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";
出力:
a, b
に 参照渡し これは、呼び出し元から見える変数を変更できることを意味します。上記のコードでは明らかに機能しません。スワップ関数を次のように変更する必要があります。
<?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";
出力:
b, a
参照によって渡すため。
PHP では、デフォルトでオブジェクトは参照コピーとして新しいオブジェクトに渡されます。
この例を参照してください......
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
さあ、これを見てください......
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.
さあ、これを見てください……
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.
これを理解していただければ幸いです。
http://www.php.net/manual/en/migration5.oop.php
PHP 5 には、新しいオブジェクト モデルがあります。PHP のオブジェクトの処理が完全に書き直され、パフォーマンスが向上し、機能が追加されました。PHP の以前のバージョンでは、オブジェクトはプリミティブ型 (整数や文字列など) のように処理されていました。このメソッドの欠点は、変数が割り当てられるとき、またはパラメータとしてメソッドに渡されるときに、意味的にオブジェクト全体がコピーされることでした。新しいアプローチでは、オブジェクトは値ではなくハンドルによって参照されます (ハンドルはオブジェクトの識別子と考えることができます)。
PHP 変数は値によって割り当てられ、関数に値によって渡され、オブジェクトを含む/表す場合は参照によって渡されます。& を使用して変数を強制的に参照渡しすることができます。
値による割り当て/参照例:
$var1 = "test";
$var2 = $var1;
$var2 = "new test";
$var3 = &$var2;
$var3 = "final test";
print ("var1: $var1, var2: $var2, var3: $var3);
出力するだろう
var1:テスト、var2:最終テスト、var3:最終試験
値渡し/参照例:
$var1 = "foo";
$var2 = "bar";
changeThem($var1, $var2);
print "var1: $var1, var2: $var2";
function changeThem($var1, &$var2){
$var1 = "FOO";
$var2 = "BAR";
}
出力は次のようになります:
var1:foo、var2 BAR
参照によって渡されるオブジェクト変数の例:
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";
}
出力は次のようになります:
FOO
(最後の例はおそらくもっと良いかもしれません...)
参照によって変数を関数に渡すことができます。この関数は元の変数を変更できます。
関数定義で参照によってパッセージを定義できます。
<?php
function changeValue(&$var)
{
$var++;
}
$result=5;
changeValue($result);
echo $result; // $result is 6 here
?>
どちらの方法でも実行できます。
「&」記号を先頭に置くと、渡す変数はその原点と同じになります。つまり:コピーを作成するのではなく、参照によって渡すことができます。
それで
$fred = 5;
$larry = & $fred;
$larry = 8;
echo $fred;//this will output 8, as larry and fred are now the same reference.
PHP5 では、プリミティブ型を含む変数は値によって渡されます。オブジェクトを含む変数は参照によって渡されます。2006 年の Linux Journal に非常に興味深い記事があり、この記事と 4 と 5 のその他の OO の違いについて言及しています。
オブジェクトは、PHP 5 では参照によって渡され、PHP 4 では値によって渡されます。デフォルトでは、変数は値によって渡されます。
ここを読んでください: http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html
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>";
属性は参照渡しでない場合でも変更可能であるため、注意してください。
出力:
スワップオブジェクト:b、swapvalues:a、b
実際にはどちらの方法も有効ですが、要件によって異なります。値を参照によって渡すと、スクリプトが遅くなることがよくあります。したがって、実行時間を考慮して変数を値で渡す方が良いでしょう。また、変数を値で渡すと、コード フローの一貫性が高まります。
元の変数を単純に変更し、新しい値が割り当てられた同じ変数名に再度戻す場合は、これを関数に使用します。
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
バージョンによって異なります。4 は値によるもの、5 は参照によるものです。