人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHP4,5での参照渡しについて具体的な利用方法を教えて下さい。

1. function example() と function &example() は、どういう場合に使いわけるのか?
2. function example($arg) と function example(&$arg) は、どう違うのか?
3. $result = example(); と $result =& example(); の具体的な違い

値渡しは、そのまま値を渡し、参照渡しは、メモリのアドレス?を渡すという程度の理解はしております。しかし、具体的などういう意味で、どういう時に使うのかがピンと来ません。
よくわからないので、自分では値渡ししか利用していませんが、他人のコードの意味がよくわからなかったり、参照渡しのコードが変更できなかったりします。

こんな時にこれを使うという具体例でも構いません。

●質問者: p_question
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:アドレス コード メモリ
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● studioes
●23ポイント

function func($n){

$n = $n + 1;

}

function funcS(&$n){

$n = $n + 1;

}

$i = 1;

func($i);

echo($i);

funcS($i);

echo($i);

このコードを動かせばわかると思います。

参照渡しでは、その変数を関数内で変更すれば、関数外でも値が変更されます。

戻り値を使うと、一つの関数は一つしか戻せませんね? しかし、複数の変数を同時に変更したい場合があります。 そういった関数の場合に、グローバル変数等を使うことなく、多くの変数を書き換えることが出来るのが参照渡しです。

また、実装により値渡しよりも参照渡しの方が高速な場合もあります(値渡しでは、メモリ上で値を複製するが、参照渡しでは場所を受け継ぐだけのため、複製する手間が省ける)

◎質問者からの返答

2.についての回答ありがとうございます。

複数の変数を同時に変更したい場合、というのがピンと来ないのですが、具体的にはどのような場合なのでしょう?

1と3についても回答をお待ちしております。


2 ● studioes
●23ポイント

複数の変数を同時に変更したい場合とは、複数の答えを戻す事でもあります。 例えば、idを元に検索して、苗字と名前をそれぞれ得たい場合等には、getName($id,&$first,&$last)の様に定義すると配列にして戻すなどの手間がいらないでしょう?

1と3は以下参照。

http://www.php.net/manual/ja/language.references.php#language.re...

1と3は密接に関連していて、1は戻り値が参照を戻すと言う表記で、3はそれを参照として$resultに入れます。

例えば、複数の変数を与えて、その変数の中から必要な変数を選択する関数などは、参照でないと、戻り値(選択された変数)を変更したところで、本来の変数は変更されません。

◎質問者からの返答

なんとなくですが、理解できるようになってきました。

getName($id,&$first,&$last)の例に関しては、以下の理解でよろしいですか?

以下の関数を呼んだ場合、returnしなくても呼び出し側の値($first, $last)が変更される。

function getName($id,&$first,&$last) {

$this->getFirstNameById($id);

$this->getLastNameById($id);

}

>例えば、複数の変数を与えて、その変数の中から必要な変数を選択する関数などは、参照でないと、戻り値(選択された変数)を変更したところで、本来の変数は変更されません。

これは、ちょっと理解できませんでした。

具体的な例で、どのような時にどのような値を渡して、どのような結果を期待しているのかを教えて頂けないでしょうか?


3 ● studioes
●22ポイント

getNameの例は

function getName($id,&$first,&$last) {

$first = '名前';

$last = '苗字';

}

$f = '';

$l = '';

getName(0,$f,$l);

echo($f.$l);

こういう事です。

参照を返すのは

$a = 2;

$b = 3;

$c = 1;

function &selectMax(&$x, &$y, &$z){

$ret =& $x;

if($ret<$y) $ret =& $y;

if($ret<$z) $ret =& $z;

return $ret;

}

$max =& selectMax(&$a,&$b,&$c);

$max += 10;

echo("a:$a, b:$b, c:$c");

こういう事です(やってる内容は普通やることはない内容ですが、効果はわかるかと思います)

◎質問者からの返答

PHP4で実行すると、Call-time pass-by-reference has been deprecatedが3つでますが、以下のようになりました。

a:2, b:13, c:1

なんとなく理解できてきました。ありがとうございました。


4 ● gekikawa
●22ポイント

1. function example() と function &example()の使い分け

リファレンスを返す(&付き関数定義)ことは、結合する変数を見付けるために関数を使用したい場合に便利です。と説明されています。

http://q.hatena.ne.jp/1173108302

の2の回答を参照しては?

http://d.hatena.ne.jp/cloned/20060510

こちらもどうぞ

3. $result = example(); と $result =& example(); の具体的な違い

example()がどのように定義されているかによって変わると思いますが、

&付きで定義されていれば、前者は(普通に)値返し、後者は1.のパターン。

&無しで定義されていれば、結果は全く同じで(普通に)値返し。

計算される時にメモリの上でどのように展開されるかが異なる程度でしょう。

と読んだのですがソースが探せませんでした

◎質問者からの返答

ありがとうございます。かなり理解できてきました。

function &example する時は、返ってきた値を&で渡さないと (例: $a =& example();) にしないと参照渡しにならないというルールが理解できました。

PHPのマニュアルにある以下の日本語訳は意味がよくわからなかったので、自分で訳しました。

Returning by-reference is useful when you want to use a function to find which variable a reference should be bound to.

元) リファレンスを返すことは、結合する変数を見付けるために関数を使用したい場合に便利です。

新) 参照返しは、参照がどの変数と結びついているのか?を探す関数を使いたい時に便利です。

なんとなくわかる文章になったような…


Unix系OSを使っている僕としては、以下の説明でピンときました。

■値渡し:

% cp hoge foo ($foo = $hoge;)

■参照渡し:

% ln hoge foo ($foo =& $hoge;)


ちなみに他の方が見る際の参考として…

参照渡しだと、値をコピーしないので、メモリーを節約できるというのは、間違いのようですね。PHPが最適化してくれるそうです。

リファレンスを返す

http://www.php.net/manual/ja/language.references.return.php

関数の値渡しと参照渡し、どちらが速い?

http://www.sound-uz.jp/php/test/first2.html

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ