4

私自身、Javaのバックグラウンドに由来する、PHPでの参照渡しの動作について、一般的に少し不満があります。これはSOで以前に話された可能性があるので、これが冗長に見えるかもしれない場合は申し訳ありません。

わかりやすくするためのコード例を示します。Personクラスがあるとします。

<?php

class Person 
{
    private $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }
}

?>

および次の使用法:

<?php

require_once __DIR__ . '/Person.php';

function changeName(Person $person)
{
    $person->setName("Michael");
}

function changePerson(Person $person)
{
    $person = new Person("Jerry");
}

$person = new Person("John");

changeName($person);
echo $person->getName() . PHP_EOL;

changePerson($person);
echo $person->getName() . PHP_EOL;

?>

今、私と、JavaまたはC#でPHPにプログラミングする他の多くの人は、上記のコードが出力されることを期待しています。

Michael
Jerry

ただし、出力しません。出力します。

Michael
Michael

&を使用して修正できることはわかっています。調べてみると、これは参照が値(参照のコピー)によって関数に渡されるためであることがわかります。しかし、これは私にとって予期しない/一貫性のない動作を構成するため、質問は次のようになります。彼らがこの方法でそれを行うことを選択した特定の理由または利点はありますか?

4

2 に答える 2

2

オブジェクト自体は実際には参照によって渡されます。そうでない場合、最初のオブジェクトechoは出力されませんMichael

2番目の例では、元のオブジェクトへの(ローカル)参照を破棄し、変数名に関数内のローカルスコープを持つ新しいオブジェクトを参照させることです。

関数内の変数に新しい値を割り当てるだけで、オブジェクトを破棄/完全に異なるものに置き換えることができるので、それは私には理にかなっています。

于 2012-12-06T16:21:09.390 に答える
1

このように使用すると、コードは期待どおりに機能します。

function changePerson(Person &$person) // <- & to state the reference
{
    $person = new Person("Jerry");
}

$person = new Person("John");

changeName($person);
echo $person->getName() . PHP_EOL;

changePerson($person);
echo $person->getName() . PHP_EOL;

出力を参照してください:http://codepad.org/eSt4Xcpr

よく言及されるPHP5OOPの重要なポイントの1つは、「オブジェクトはデフォルトで参照によって渡される」ということです。これは完全には真実ではありません。

PHP参照はエイリアスであり、2つの異なる変数が同じ値に書き込むことができます。PHP 5以降、オブジェクト変数にはオブジェクト自体が値として含まれなくなりました。これには、オブジェクトアクセサが実際のオブジェクトを見つけることができるオブジェクト識別子のみが含まれています。オブジェクトが引数によって送信されたり、返されたり、別の変数に割り当てられたりする場合、異なる変数はエイリアスではありません。同じオブジェクトを指す識別子のコピーを保持します。

http://php.net/manual/en/language.oop5.references.phpから引用。

于 2012-12-06T16:36:59.403 に答える