ホームページ >バックエンド開発 >PHPチュートリアル >PHPの使い方の詳しい説明抜粋(&)
PHP引用(&)の使い方を詳しく解説
PHP初心者向け&引用について
公式ドキュメント:
1.引用とは:http:// www.php.net/manual /zh/ language.references.whatare.php
2. リファレンスの内容: http://www.php.net/manual/zh/ language.references.whatdo .php
3. 参照の受け渡し: http://www.php.net/manual/zh/ language.references.pass.php
4. 参照の戻り: http://www.php.net/manual /zh/ language.references.return.php
PHP リファレンス (つまり、変数、関数、オブジェクトなどの前にアンパサンドを追加します)
PHP における参照の意味は、異なる名前が同じ変数の内容にアクセスすることです。
C言語のポインタとは異なります。 C言語におけるポインタは変数の内容とメモリ上に格納されているアドレスを格納します。
1. 変数参照
PHP 参照を使用すると、2 つの変数を使用して同じコンテンツを指すことができます
$a="ABC";
$b =&$a;
echo $a;//ここに出力: ABC
echo $b;//ここに出力します: ABC
$b="EFG";
echo $a;//ここでの $a の値は EFG になるため、EFG
が出力されます echo $b;//ここでは EFG
?>
2. 関数参照の受け渡し(アドレスによる呼び出し )
アドレスによる呼び出しの詳細については説明しません。コードは
ここで test(1); を使用するとエラーが発生するので注意してください。あなた自身。
注:
上記の "test($b);" の $b の前に & 記号を追加しないでください。関数「call_user_func_array」でパラメータを参照したい場合は、次のコードに示すように & 記号が必要です:
3. 関数参照 return
次の説明:
この方法で得られるもの $a=test(); は、実際には関数参照の戻り値ではなく、通常の関数呼び出しと何ら変わりません。は PHP の規定です
PHP では、関数の参照戻り値は $a=&test();
によって取得されると規定されています。 参照戻り値とは何かについては、PHP マニュアルに次のように書かれています。関数を使用して、どの変数にバインドされるべき参照を見つけるか。) このナンセンスなため、私は長い間理解できませんでした。
上記の例を使って説明すると、呼び出します。
$a=test() の方法で関数を作成すると、$a を与えるだけで、関数内の $b
には影響しません。関数は $a=&test() を通じて呼び出され、その関数は $b 変数を $b に返すことです。 変数 $a のメモリ アドレスは同じ場所
を指し、同じ結果が得られます ($a=& $b;) したがって、$a の値を変更すると、$b の値も変更されます。つまり、
$a=&test();
$a=5;
を実行すると、$b の値が変更されます。は 5 になります
これは、関数の参照戻り値を静的変数を使用して誰もが理解できるようにするためです。実際、関数の参照戻り値はオブジェクトでよく使用されます。
が添付されています。公式 PHP の例:
これは、ポインタを使用してクラス内の変数にアクセスする方法です。
class talker{
private $data = 'Hi ';
public function & get(){
return $this->data;
}
public function out(){
echo $this-> ;data;
}
}
$aa = new talker();
$d = &$aa->get();
$aa->out();
$d = '方法';
$aa->out ();
$d = 'アレ';
$aa->out ();
$d = 'あなた';
$aa->out();
?>
出力は "HiHowAreYou"
4. オブジェクト参照
クラス a {
var $abc="ABC";
}
$b =new a;
$c=$b;
echo $b->abc;//ABC を出力
ここに echo $c->abc;// ここに ABC
を出力 $b ->abc="DEF";
echo $c->abc;// DEF
を出力?> ;
上記のコードは PHP5 での実行効果です
PHP5 では、オブジェクトの割り当ては参照プロセスです。上記の列の $b=new a; $c=$b; は、実際には $b=new a; $c=&$b;
PHP5 のデフォルトではオブジェクトを参照によって呼び出すことになります。オブジェクトのコピーを作成し、元のオブジェクトへの変更がコピーに影響しないようにしたい場合、PHP5 は __clone と呼ばれる特別なメソッドを定義します。
PHP 5 では、new は自動的に参照を返すため、ここでの =& の使用は廃止され、E_STRICT レベルのメッセージが生成されます。
php4 では、オブジェクトの割り当てはコピー プロセスです。
例: $b=new a、ここで new a は匿名 a を生成しますオブジェクト インスタンスであり、この時点の $b はこの匿名オブジェクトのコピーです。同様に、$c=$b も $b の内容のコピーです。したがって、php4 では、メモリ領域を節約するために、$b=new a を参照モード、つまり $b=& new a に変更するのが一般的です。
これが別の公式の例です:
php5 では、「オブジェクト参照」機能を実現するために他に何も追加する必要はありません:
class foo{
protected $name;
function __construct($str){
$this->name = $str;
}
function __toString(){
return 「私の名前は「」です。 $this->name .’」 そして私は 「「 . __CLASS__ . 」」に住んでいます。 。 "n";
}
function setName($str){
$this->name = $str;
}
}
class MasterOne{
protected $foo;
function __construct($f){
$this->foo = $f;
}
function __toString(){
「マスター: 」を返します。 __クラス__ 。 ' | ふー: ' 。 $this->foo 。 "n";
}
function setFooName($str){
$this->foo->setName( $str );
}
}
class MasterTwo{
protected $foo;
function __construct($f){
$this->foo = $f;
}
function __toString (){
return 'マスター: ' 。 __クラス__ 。 ' | ふー: ' 。 $this->foo 。 "n";
}
function setFooName($str){
$this->foo->setName( $str );
}
}
$bar = new foo('bar');
print("n");
print("$bar の作成と $barn の印刷のみ");
print($bar );
print("n");
print("現在、$baz は $bar を参照し、$bar と $bazn を印刷しています");
$baz =& $bar;
print( $bar );
print("n");
print("今、MasterOne と Two を作成し、両方のコンストラクターに $bar を渡していますn");
$m1 = 新しい MasterOne($ bar );
$m2 = new MasterTwo( $bar );
print( $m1 );
print( $m2 );
print("n");
print("現在、$bar の値を変更し、$bar と $bazn を印刷しています");
$bar->setName('baz');
print($bar);
print($baz );
print("n");
print("再び MasterOne と Twon を印刷中");
print($m1);
print($m2);
print("n");
print("MasterTwo の foo 名を変更し、再び MasterOne と Twon を印刷します");
$m2->setFooName('MasterTwo's Foo');
print( $m1 );
print( $m2 );
print("$bar と $bazn も印刷します");
print( $bar );
print( $baz );
?>
出力:
$bar の作成と $bar の印刷のみ
私の名前は「bar」で、「foo」に住んでいます。
現在、$baz は $bar を参照し、$bar と $baz を出力しています
私の名前は「bar」で、私は「foo」に住んでいます。
今、MasterOne と Two を作成し、$bar を渡しています。両方のコンストラクター
マスター: MasterOne | foo: 私の名前は「バー」で、「foo」に住んでいます。
マスター: MasterTwo | foo: 私の名前は「bar」で、私は「foo」に住んでいます。
現在、$bar の値を変更し、$bar と $baz を出力しています
私の名前は「baz」で、私は住んでいます"foo" にあります。
私の名前は "baz" で、"foo" に住んでいます。
今、もう一度印刷しています。MasterOne と Two
Master: MasterOne | foo: 私の名前は「baz」で、「foo」に住んでいます。
マスター: MasterTwo | foo: 私の名前は「baz」で、私は「foo」に住んでいます。
今、MasterTwo の foo 名を変更し、再び MasterOne と Two を印刷しています
マスター: MasterOne | foo: 私の名前は「MasterTwo's Foo」で、「foo」に住んでいます。
マスター: MasterTwo | foo: 私の名前は「MasterTwo's Foo」で、「foo」に住んでいます。
$bar と $baz も印刷します
私の名前は「MasterTwo's Foo」で、「foo」に住んでいます。
私の名前は「MasterTwo's Foo」で、「foo」に住んでいます。
上の例子解析:
$bar = new foo('bar');
$m1 = new MasterOne( $bar );
$m2 = new MasterTwo( $bar );
php4 では、前述のように、1 つのオブジェクトの例が当接着外の 1 つのオブジェクトのプロパティを削除する必要があります。以下のようなものです。
class foo{
var $bar;
function setBar(&$newBar){
$this->bar =& newBar;
}
}
5. 引用的作用
如果程序比较大,同じオブジェクトへの参照の量が多すぎるため、そのオブジェクトを完了した後に手動で削除し、「&」方式で手動で削除し、その後 $var=null 方式で削除することが望ましいです。 それ以外の場合は、php5 の承認方法も使用します。 また、php5 では、多数のグループの転送に対して、"&" 方式を使用して内部保存スペースを節約しています。例:
$a = 1;
$b =& $a;
未設定 ($a);
$b は設定解除されず、$a のみです。 $var には、局所全体の変量に関する引用がすべて上に用意されています。 つまり、このことと同じことです:
数集合はこの点を避けます。
例 関数内でグローバル変数を参照する
< ;?php
$var1 = "変数の例";
$var2 = "";
function global_references($use_globals)
{
global $var1, $var2;
if (!$use_globals) {
$var2 =& $var1; // 関数内でのみ表示されます
} else {
$GLOBALS["var2"] =& $var1;グローバルコンテキストでも
}
}
global_references(false);
echo "var2 is set to '$var2'n" // var2 は ''
に設定されます。 global_references(true);
echo "var2 is set to '$var2'n"; // var2 は 'サンプル変数' に設定されます
?>
8.$this
オブジェクトのメソッド内で、 $this は常に、呼び出し元のオブジェクトへの参照です。
//ここでまたちょっとしたエピソードです
php におけるアドレスのポインティング (ポインタに似た) 関数はユーザー自身が実装するのではなく、Zend コアによって実装され、参照されますin php これは「コピーオンライト」の原則です。つまり、書き込み操作が発生しない限り、同じアドレスを指す変数やオブジェクトはコピーされません。
わかりやすく言うと
1: 次のコードがある場合
$a="ABC";
$b=&$ a ;
?>
実際、この時点では、$a と $b は異なるメモリを占有するのではなく、同じメモリ アドレスを指します
2: 上記のコードに次のコードを追加すると
$a="EFG";
?>
$a と $b が指すメモリ内のデータを書き換える必要があるため、この時点で Zend コアは $a の $b 用のデータ コピーを自動的に決定して自動的に生成し、再書き込みします。 - ストレージ用のメモリの一部を申請する
PHP 参照 (つまり、変数、関数、オブジェクトなどの前にアンパサンドを追加すること) は、初心者には有料のトピックです。 PHP 参照を正しく理解することが重要です。これはパフォーマンスに大きな影響を及ぼし、誤解がプログラム エラーにつながる可能性があります。
多くの人は、PHP の参照が C のポインターと同じであると誤解しています。実際には、それらは異なり、大きく異なります。配列転送処理中に明示的に宣言する必要のない C 言語のポインタを除き、その他のポイントは * を使用して定義する必要があります。ただし、PHP では (ポインタと同様の) アドレスを指す機能が実装されていません。はい、PHP の参照は「コピーオンライト」の原則を採用しています。つまり、書き込み操作が発生しない限り、同じアドレスを指す変数やオブジェクトはコピーされません。例: 次のコード:
$a = array('a','c'...'n');
$b = $a ;
プログラムがここまでのみ実行する場合、$a と $b は同じですが、C のように異なるメモリ空間を占有することはなく、同じメモリを指します。 php と c の違いは、$ b=&$a と書く必要はありません。これは、$b が $a のメモリを指していることを意味します。zend は、いつ実装すべきかを非常に賢明に支援します。このように扱われる必要がある場合と、このように扱われるべきではない場合。
後で次のコードを書き続ける場合は、関数を追加し、パラメーターを参照渡しして、配列のサイズを出力します。
function printArray(&$arr) // 参照渡し
{
print(count($arr));
}
printArray($a);
上記のコードでは、$a 配列を参照によって printArray() 関数に渡します。zend エンジンは、printArray() が原因でエラーが発生すると考えます。 $a でエラーが発生しました。この時点で、$a のデータ コピーが $b 用に自動的に作成され、メモリの一部がストレージに再適用されます。これが、前述した「コピーオンライト」の概念です。
上記のコードを次のように変更すると:
function printArray($arr) // 値の転送
{
print ( count($arr));
}
printArray($a);
上記のコードは $a 値を printArray() に直接渡します。現時点では参照転送がないため、コピーオンライトは行われません。
上記の 2 行のコードの実行効率をテストできます。たとえば、ループを 1000 回外に追加して、実行にかかる時間を確認します。その結果、参照が不適切に使用された場合に影響を受けることがわかります。パフォーマンスが 30% 以上低下する原因となります。
自己理解: 値渡しの場合は関数内の引数とは無関係でローカル変数の役割に相当しますが、アドレス(参照)渡しの場合は関数内のパラメータに関係します。関数内のパラメータ。グローバル変数の役割に相当します。パフォーマンスの観点からは、上記の分析を見るだけで十分です。 .