参照がPHPでめったに使用されないのはなぜですか?


26

私はC ++の知識があり、ポインターが一般的に使用されていることを知っていますが、PHPのオープンソースコードを調べ始め、メソッドで参照を使用するコードを見たことはありません。

代わりに、コードは、変数への参照をメソッドに渡す代わりに常に戻り値を使用します。その後、変数の値が変更され、そのまま返されます。

参照を使用するとメモリ使用量が少なくなるので、なぜPHPで使用されないのですか?


19
参照渡しパラメータの使用は「副作用プログラミング」です。関数を使用して単一の値を返すことは、コードの読み取り時に非常に明確です。つまり、かなりの数のPHPコア関数が参照を使用しています。
13

3
PHPはデフォルトでオブジェクトを参照渡しします。

2
配列ソートは、参照渡しコアPHP関数のプライムexanmpleある
マークベイカー

2
PHPの参照はありませんポインタ、彼らが表示される場所を完全にそれらを期待していない場合が多いお尻の痛みです。
lanzz

2
複数の返品が必要な場合、return array($foo, $bar);およびlist($A, $B) = foobar();
Izkata

回答:


49

参照がほとんど使用されないというあなたの主張は誤りです。他の人がすでに言及しているように、参照を使用するネイティブ関数がたくさんあります。注目すべき例には、配列ソート関数preg_match()/がありpreg_match_all()ます。コードでこれらの関数のいずれかを使用している場合、参照も使用しています。

さらに、PHPの参照ポインターではありません。あなたはC ++のバックグラウンドから来ているので混乱は理解できますが、PHP参照はまったく異なる獣であり、シンボルテーブルのエイリアスです。C ++参照から予想されるパフォーマンスの向上は、PHP参照には適用されません。

実際、ほとんどのシナリオでは、値渡しは参照渡しよりも高速であり、メモリ集約度が低くなります。PHPのコアであるZend Engineは、変更されるまで変数のコピーを作成しないコピーオンライト最適化メカニズムを使用します。参照渡しは通常、コピーオンライトパターンを破壊し、値を変更するかどうかにかかわらずコピーが必要です。

必要なときにPHPで参照を使用することを恐れないでください。しかし、単に最適化を試みるために使用しないでください。時期尚早の最適化がすべての悪の根源であることを忘れないでください。

参考文献:


@NikiCを修正していただきありがとうございます。
怠la

答えを完成させるために、すべてのオブジェクトがPHPで参照渡しされることを指摘しておくといいでしょう。
フローリアンマーゲイン

@FlorianMargaineそれは完全に正確ではありません(詳細は2番目のリンクを参照してください)。
ヤンニス

2
@FlorianMargaineいいえ、2つは非常に異なっており、なぜそうなのかを理解することが重要です。
phant0m

3
@FlorianMargaineいいえ、と仮定するオブジェクトがされた PHPで参照によって渡さ:f($obj)与えられfunction f($x) { $x = new X; }、持っています$objを参照してください。異なるの呼び出し前よりオブジェクトf()。ただし、オブジェクト参照渡しではないため、PHPでこれを実行する場合、$ objは変更されません。そのようにして、PHPはJavaと同じことを行います。
phant0m

8

PHPは、コピーオンライト機能を既に実行しており、何かを変更するまで新しい値を作成しないため、参照を使用しても多くのメモリが節約されません。これを行うと、PHPが内部的にメモリの使用量を削減し、事態をさらに悪化させるいくつかの機能を混乱させる可能性があります。

それに加えて、参照は一般的に物事を少し魔法的にしすぎるという事実を追加します。デフォルト、つまりほとんどの人が期待しているのは、値渡しです。$i関数に渡すとき、その関数が神秘的に$i他の何かに完全に変化するかどうかを気にしなければならないため、物事を非常に複雑にし、万が一のために防御的なコピーを作成します。($i値がオブジェクトである場合、すでに変更できますが、私の意見ではそうすべきではありません。)

基本的に、私は意味、私がすることを期待変数参照渡し「アウト」パラメータのための便利を見つけるだろう取り戻す機能ではなく、中域、ア・ラからpreg_matchのを&$matches。渡されたオブジェクトを明確に変更する関数であっても、sortまたはのようにarray_pop、少し厄介な感じがしますが...それが私たちが行き詰まっているものです。


5

PHPはWeb指向の言語です。
Webページは高速で提供され、軽量である必要があります。
通常のPHPプログラムは、ほんの数秒で動作し、数百キロバイトのメモリを消費します。
このような最適化は使用できません。


1
この。ポインター/参照は必要ありません。C++のような低レベルで混乱しないためです。
ケネス

8
この投稿が5+になる理由??? a)質問に答えないb)正しくない

1
それで、参照は遅く、メモリを大量に消費しますか?
ロケット危険物

1
@RocketHazmatはい、奇妙なことに、それは本当です。
ヤニス

3

その場でいくつかの理由:

  • PHPはスクリプト言語であり、コアの組み込みソフトウェアとして使用することを目的としていません(基本的に、メモリはスクリプトの最後でクリアされます)。
  • PHP5以降、オブジェクトパラメータには参照渡しが暗黙的に行われます(したがって、PHPは「後ろに」参照渡しを使用します)。

1
2番目のポイントについては、php.net / manual / en / language.oop5.references.phpを参照してください。
ヤニス

2

これは開発者の選択に過ぎず、言語とは無関係だと思います。多数のPHPコード(組み込みおよび非組み込み)が参照を使用します。PHPの配列関数を見てください。それらの多くは参照を使用しています。 preg_match参照を使用します。

開発者が参照を使用しないことを選択した理由の1つは、混乱を招く可能性があるためだと思います。関数を呼び出すと、変数が参照であるため、変数の1つが更新される場合と更新されない場合があります。したがって、デバッグするときに、$xjsut の値が魔法のように変更された理由が明確でない場合があります。


1

質問の根本的な問題は、これがC ++でも一般的であると想定していることです。そうではありません。出力パラメータは好きではなく、可能な限り使用しません。これらは、CスタイルAPIでのみ一般的です。


0

そうする多くの php関数を知っています。preg_match()たとえば、ご覧ください。$matches参照渡しされます

参照により引数を取る関数を自分で作成する場合は、次の構文を使用します

function byref(&$a, &$b, $c) {
    $a += $c;
    $b += $c;
    return $a * $b;
}

$ aと$ bは参照によって渡されます$ cは値によって渡されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.