PHPの参照渡しについて

このQ&Aのポイント
  • PHPの参照渡しについて説明します
  • 変数の参照によってオブジェクトの状態を共有することができます
  • 明示的な参照渡しでは、オブジェクトの状態が共有されるだけでなく、変数の値も変更されます
回答を見る
  • ベストアンサー

PHPの参照渡しについて

以下のようなコードがあったとき $obj = new stdClass(); $foo = $obj; この場合、動作は いわゆる【参照の値渡し】というとらえかたでよいのでしょうか? 変数$obj には、 new stdClass();という記述によって 新規に作成されたオブジェクトの参照(※正確には別のメモリ内に保持されたオブジェクトのアドレス) が保持されるわけですよね? そのとき $foo = $obj; というコードは$objが保持するオブジェクトのアドレス値を$fooという変数にも コピーするという動作を意味するわけですよね。 この場合、両変数を用いて生成されたオブジェクトのプロパティなどの状態を 共有することとができます。 しかしながら変数$fooに別の値、例えば文字列を代入すうると $foo = "文字列"; とすると$fooの値が変更され$objの値は変更されません。 対して、次のようなコードがあった場合 $foo = &$obj; というコード、これはPHPにおける参照渡しですが、 この場合は$objが指し示す、オブジェクトが保持されているメモリ上のアドレスではなく そのメモリ上に確保された変数$objそのもののアドレスが$fooという変数にコピー? されるのでしょうか? この明示的な参照渡しだと、オブジェクトの状態を共有するのはもちろん $foo = "オブジェクト破棄"; と片方に文字列を代入すると print $obj; 同様に文字列にかわってしまいます。 この本来の意味?であろう参照渡しとは実際 $fooに変数$objそのもののアドレスが保持されるという 解釈でよいのでしょうか? おくわしいかたご教授ください。

  • PHP
  • 回答数3
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4847/10260)
回答No.3

>PHPにおける参照渡し(&をつかう)はC++におけるエイリアスとおなじ処理(同義)ですか? そうですね。 $foo = &$obj; した以降は、$foo と $obj への代入や参照はどちらも同一になります。別名。 この結びつきは、 unset($foo); で解除されます。 http://www.php.net/manual/ja/language.references.whatare.php から始まる数ページを読んでください。

その他の回答 (2)

noname#244856
noname#244856
回答No.2

以前私もぶち当たった壁で、そのとき詳しく調べてYahoo!知恵袋で知恵ノートにまとめました。 http://note.chiebukuro.yahoo.co.jp/detail/n127275 tezcelloさんから指摘がある通り、PHPに「ポインタ」の概念はないのですが、考え方的にはこれで理解が出来るはずです。 「ポインタ」ではなく「オブジェクトID」で考えるならば、 $obj = new stdClass(); $foo = $obj; 「変数はオブジェクト型、オブジェクトIDは$objの現在の値」 $foo = &$obj; 「変数はオブジェクト型、オブジェクトIDは$objの参照する値」

  • agunuz
  • ベストアンサー率65% (288/438)
回答No.1

RTFM. http://www.php.net/manual/ja/language.operators.assignment.php ------- 引用ここから PHP では通常は値による代入になりますが、オブジェクト型については例外です。 PHP 5 以降、オブジェクトは参照で代入されるようになりました。オブジェクトを明示的にコピーするには clone キーワードを使います。 ------- 引用ここまで

1000vicki
質問者

補足

えーちょっとしりたかったことと、ご回答いただいたものが違ったので 質問をかえますね。 ずばり PHPにおける参照渡し(&をつかう)は C++におけるエイリアスとおなじ処理(同義)ですか?

関連するQ&A

  • PHP5での参照渡しについて

    お世話になっております。 3点質問させて下さい。 1.PHP5での参照渡しについて PHP5では、参照渡しがデフォルトという記事を読んだのですが、classを使わず、以下のようにfunctionのみで記述した場合、参照渡しになっている気配がありません。 - $test = "テスト"; function a($a){ $a = "参照渡し"; } a($test); echo $test; - 結果:テスト &$aとすると参照渡しになりますが、classを使わない場合はPHP5のデフォルトが参照渡しというのを意識する必要は無く、&を用いた参照渡しを利用する形で良いのでしょうか? 2.オブジェクトについて オブジェクト=class だと思っても良いのでしょうか? また、独立した関数では無く、classを利用した方が良い場面というのはどういう時なのでしょうか? classやオブジェクト指向というものへの私の理解が足りてない事でこのような疑問を抱く事になっていると思います。 classやPHP5のオブジェクト指向について学習するのに便利な書籍やサイトなどあれば紹介して頂けないでしょうか? 3.$_POSTや$_GETについて 他の方のソースを見ていると、何かの処理後にPOSTの値を別の変数に入れている方が多いように思えます。 私もそれにならってPOSTの値をいじる場合は、 変数 = 関数($_POST["test"]); とするようにしています。 ですが、 $_POST["test"] = 関数($_POST["test"]); とするのは何か都合が悪い事があるのでしょうか? 要領を得ない質問で申し訳ありませんが、回答頂けましたら嬉しいです。

    • ベストアンサー
    • PHP
  • javaでは基本型の参照渡しは無理ですか?

    先日のjavaの授業で値渡しと参照渡しについて学びました。 授業では オブジェクトは参照渡しになり 基本型は値渡しにされる(参照渡しは不可能) と教えられました。 オブジェクトを値渡しにできないのはなんとなく納得できたのですが 基本型を参照渡しにできないのが納得できません。 そこで 1.基本型を参照渡しにすることはできないのか? 2.基本型を参照渡しすることができないのはなぜか? 3.オブジェクトを値渡しすることができないのはなぜか? の3点を教えて頂きたいです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • 参照渡しで分からないことがあります。

    参照渡し 参照渡しで分からないことがあります。 以下のコードです。一部抜粋のコードです。 > class CSample > { > public: > CSample(){ m_num = 123; } // コンストラクタ > int& get(){ return m_num; } // メンバ変数を参照戻し > private: > int m_num; > }; > ~~~~~~~ >int& alias1 = get(); >alias1 *= 2; >int& alias2 = get() + alias1; // このようにブロックの途中で宣言できる ~~~~~~~ このコードの中の >int& alias2 = get() + alias1; が分からないところです。 参照をalias2に設定しているところだと思われますがget()の参照戻しのアドレスと alias1の参照のアドレスと2つの参照を設定しているのが分かりません、この2つは同じアドレスをさしているのでこのサンプルでは支障はないように思えますが。 この場合は、式右辺のget()+alias1の2つの参照を足しているのが分からないので教えてください。 なおこのコードが掲載されているサイトは以下です。 http://www.geocities.jp/ky_webid/cpp/language/015.html

  • PHPの参照わたしについて

    PHPの参照わたしについて質問です。 例えば、ユーザー定義関数の引数を参照渡しとする場合 function test(&$string){ $string .="参照渡し"; } $aaa = "文字列"; test($aaa); print $aaa; 等とすると、一切値のコピーがおこなわれませんよね? 次に function test($string){ $string . ="参照渡し"; return $string; } $bbb ="文字列"; $ccc = test($bbb); print $ccc; と上記のようにした場合、値のコピーが行われるのは 関数の引数に渡すときと 返り値を返すときの2回行われてるんですかね? もし、値のコピーが二回行われているとするなら 次のようにしたら値のコピーは一度だけ・・・少なくとも上の例よりPHPの動作より 軽い?ものになるのでしょうか・ function &test($string){ $string .= "参照わたし"; return $string; } $ddd = "文字列"; $eee =& test($ccc); //ここで関数の返り値を参照渡しする この場合、値のコピーが行われるのは関数に引数を渡すときの1回だけでしょうか? copy on write による動きは無視しておいて、 オブジェクト指向なプログラムでなくユーザー定義関数であれば このように関数の返り値を参照わたしにした方が、理論的?には早いのでしょうか? この場合、引数も参照渡しにすると破壊的関数になるのでそれは避けたいが、 なるべく値のコピーは防ぎたいという状況だと考えてください。 実際、こんな風にすべてのユーザー定義関数の返り値を参照にして定義するなんてこと おそらくないとおもうのですが、単純にコピーの回数がきになったのです。 よろしく御願いします。

    • ベストアンサー
    • PHP
  • 参照渡しやリファレンスを返す事について

    今疑問に思っているのが、「&」を付ける全ての事象についてす。 今まで参照渡しの方が効率や都合が良い場合にしか利用していませんで したが、「特に値渡しで構わない場合も、参照渡しにした方が良いの か?」という事から出てきた疑問です。 引数の値を直接操作する事はあまり良くない、と言われるのはこの辺の 絡みだと思うのですが、仮に関数内で引数の値を再セットする事を 忠実に守っていた場合、値渡しより常に参照渡しである方がメモリ 効率は良いと思います。(結局関数内で値渡しをする為、消費量としては 大きいと思いますが) 個人的には必要のある時にしか参照渡しを行わないという考えを変えるつもりは ありませんが(それが妥当な目的と利用法であると思うので)、 プロな方としてはどうなのかな、という事を思ってしまったのです。 次に、仮に変数同士で行った場合、ポインタもどきの動作をしている 事から、意味合いは通じるのですが、インスタンスを生成する場合や そのメソッドを呼び出して戻り値がオブジェクトの場合に見受けられます。 (マニュアルを見るとPHP5の場合、インスタンス生成時にそれを利用する 事は非推奨のようですが) 疑問なのは、インスタンスを初めて生成してオブジェクトが作られているのに 「&」で何を参照しに行っているのか?(クラスという雛形?) メソッドが終了したら内部の変数は開放されると思うが、それを参照 する事が何故可能なのか? リファレンス元をunset()してもリファレンス先が消えない事と同じ意味か? そういうものだと言ってしまえばそれでおしまいですが、 そういう疑問があるせいか、それの使いどころが分かりません。 加えてメソッドに関しては、呼び出し時に「&」をつけていたり メソッドの定義自体に「&」があったりして、使い方が分かりません。 呼び出し時の「&」は戻り値の参照でしょうけど、メソッド定義自体の 「&」が意味不明です。 ここばっかりはマニュアルを見ても理解出来ませんでした。 定義の参照って?という感じで考えが止まってしまいます。 (呼び出し時は、require等がされた時点でメモリで格納されている対象を見ている、という事なのか?) どなたかご教示願います。 今、かなりPHPについて悩んできてしまいました(笑)

    • ベストアンサー
    • PHP
  • 関数で値渡しと参照渡しではどっちがメモリを使うのか

    クラスAの大きなサイズのオブジェクトを、 クラスBで処理するメソッドを書こうとしています。 ◆質問 このとき、クラスBでは、byval で記載するのと、byrefで記載するのでは、 どちらの方がメモリを食わないのでしょうか? ◆自分の想定 (1)byrefで記載した場合、そのオブジェクトのポインタを受け取って処理するため、あんまりメモリは食わない。 (2)byvalで記載した場合、ある意味、.clone のような処理がされて、渡されたオブジェクトと同じサイズのメモリを食う? ※処理しようとしていることは、特に参照渡しされた変数の値を修正するような類ではないです。 なので、「オブジェクトを不用意にいじってしまう危険性」などの観点は無視し、メモリの観点の話です。 ちなみに、メソッドを、shareで宣言しようが、インスタンス化してからじゃないと使えないように宣言しようが、その関数のために使用されるメモリのサイズ(※クラスBのインスタンス化のためのメモリではないという意味)は変わらないということで合っていますでしょうか? .

  • 参照型変数について

    オブジェクトはメモリ上どの場所に生成されたか分からないので、参照型変数を生成して、そのオブジェクトのアドレスが分かるとのことですが、同じように参照型変数もメモリ上で生成されるのだから、アドレスがあると思うのですが、どうやれば分かるのですか?

    • ベストアンサー
    • Java
  • 参照渡しの参照渡し

    こんにちは。PHPでの質問をさせて頂きます。 PHPで以下のようなコードを書いた場合値が参照渡しで返って来ません。 解決法をご存知の方がいたら是非教えて下さい。お願いします。 function &hoge(&$data,$key){  $ret=$data[$key]; } //これもダメ function hoge(&$data,$key,&ret){  $ret=$data[$key]; }

    • 締切済み
    • PHP
  • 参照型のオフセット取得

    C++でリフレクションを実装するため、全メンバー変数のオフセット をoffsetofで取得し、メンバ変数名とオフセットをstd::mapに登録 しようとしています。 ここで質問なのですが、参照型に対してoffsetofを取得しようとすると アクセス違反で落ちてしまいます。原因を調べてみると、クラスの オブジェクトがobj、メンバ変数が参照型refだとすると、&obj.refは ref変数のアドレスを返すのでは無く、refが指している変数のアドレス を返してくるのが原因でした。 長くなりましたが、ref変数のアドレスを取得する方法、またはオフセット を取得する方法は無いのでしょうか?これが出来ないと、参照型については未サポートにするしか無くなってしまいます><

  • 参照渡しを使う理由がわかりません

    PEARの 'HTML/QuickForm.php' を利用し、フォームを作成しようと思いました。 以下ソースを入力していたところ、ラジオボタンのところで参照渡しが出てきました。 【$obj =& $form->addElement("radio", "age", "年代:", "10代", "10", array("checked"));】 ラジオボタン以前のテキストボックス等は = だったのですが、なぜ、 ラジオボタンだけ参照渡しをするのでしょうか? 何かメリットがあるから参照渡しをしているのだと思うのですが…。 ご教授よろしくお願いします ====ソースここから <?php // 必要パッケージの読込み require('HTML/QuickForm.php'); // ●Form要素の構築 $form = new HTML_Quickform("test","POST"); // formの設定 $form->setRequiredNote("<span style=color:red>*</span> 記入必須項目"); // 記入必須項目の説明用文字列設定 $form->setJsWarnings("エラー",""); // Javascriptエラーの際の文字列設定 // header 要素を追加 $form->addElement("header", "title", "情報を記入"); // hidden 要素を追加 $form->addElement("hidden", "id", uniqid("")); // text 要素を追加 $form->addElement("text", "name", "名前:", array("value"=>"","size"=>"24")); // radio 要素を追加 $obj =& $form->addElement("radio", "age", "年代:", "10代", "10", array("checked")); // デフォルトでチェックの設定にする $obj->setChecked(TRUE); $form->addElement("radio", "age", "", "20代", "20"); $form->addElement("radio", "age", "", "30代", "30"); $form->addElement("radio", "age", "", "40代", "40"); : : =========ソースここまで

    • ベストアンサー
    • PHP

専門家に質問してみよう