ホームページ  >  記事  >  バックエンド開発  >  セクション 15 -- Zend Engine_PHP チュートリアルの開発

セクション 15 -- Zend Engine_PHP チュートリアルの開発

WBOY
WBOYオリジナル
2016-07-21 16:01:16827ブラウズ

/*
+---------------------------------------------- -- ----------------------------------+
| = この記事は Haohappy<> ; = 章のクラスとオブジェクトのメモ
| = 不要なトラブルを避けるため、転載はご遠慮ください
| PHP 愛好家は一緒に進歩しましょう
| = PHP5 Research Center: http://blog.csdn.net/haohappy2004
+---------------------- -------------------------------------------------- -- ---+
*/
セクション 15 -- Zend エンジンの開発
この章の最後のセクションでは、Zeev が Zend エンジンによってもたらされたオブジェクト モデルについて説明し、以前のバージョンのモデルとの関係について特に言及しています。 PHP の違いは何ですか? 1997 年の夏に PHP3 を開発したとき、PHP をオブジェクト指向にする計画はありませんでした。しかし、PHP3 は純粋に手続き型の言語でした。 1997 年 8 月 27 日、PHP に新しい機能を追加するには最小限の議論しか必要としませんでした。当時は PHP を研究する人が少なすぎたため、1997 年 8 月から PHP が開始されました。これはオブジェクト指向プログラミング言語への最初のステップです
実際、この設計には関連するアイデアがほとんどないため、このバージョンで使用されるオブジェクトのサポートは十分ではありません。配列 $foo["bar"] を使用する代わりに、より見栄えの良い $foo->bar を使用できます。オブジェクト指向アプローチの主な利点は、メンバー関数またはメソッドを通じて機能を保存できることです。 6.18 は典型的なコード ブロックを示していますが、例 6.19 のアプローチと大きな違いはありません。 ;?php
クラスの例
{
var $value = "何らかの値";
function PrintValue()
print $this->value; }

} $obj = new Example( ; function PrintValue ($arr) ) print $arr["value"]; function CreateExample()
$arr["PrintValue"] = "PrintValue"; }
$ Arr = Createexample ();
// PHP の間接参照を使用する
$ Arr [" Printvalue "] ($ arr); ただし、これら 2 つのオプションはそうではないことを考慮します。 PHP3 ではそれとは異なり、「構文のホワイトウォッシュ」としてのみオブジェクト モデルを使用して配列にアクセスできます。
PHP を使用したい オブジェクト指向開発を行うようになった人、特にデザイン パターンを使用したい人は、すぐにそのことに気づきました。幸いなことに、当時 (PHP3 時代) はオブジェクト指向開発に PHP を使用したいと考えていた人は多くありませんでした。これが、新しいバージョンでは、PHP でさまざまな識別子を使用できるようにする参照の概念を導入しました。これは、同じ変数に複数の名前を使用できることを意味します。例 6.20 のように名前を付けます。



コードをコピーします。コードは次のとおりです:
$a = 5;
//$b は $a と同じメモリの場所を指し、$a はメモリ内の同じアドレスを指します
$b = &$a; //we ' $b を変更しています。$a が $b を変更することを指しているので、指しているアドレスも変わります
//同じ場所 - それも変わります $a が指すアドレスも変わります
$b = 7
//prints 7 出力 7
print $a;
?>
相互に参照するオブジェクトのネットワークを構築することは、すべてのオブジェクト指向設計パターンの基礎であるため、参照によってより強力なオブジェクトを作成できるようになり、この改善は非常に重要です。 PHP は、他の種類のデータと同じアプローチでオブジェクトを処理します。PHP4 プログラマーなら誰でも言うように、アプリケーションは WTMA (Way Too Many Ampersands) 症候群に悩まされることになります。実際のアプリケーションを構築するときは苦痛です。例 6.21 を見ると理解できると思います。
1 クラス MyFoo {
2 関数 MyFoo()
3 {
4 $this->me = &$this;  
5 $this->value = 5;  
6 }
7
8 関数 setValue($val)
9 {
10 $this->value = $val;  
11 }
12
13 関数getValue()
14 {
15 return $this->value;  
16 }
17
18 関数getValueFromMe()
19 {
20 return $this->me->value;  
21 }
22 }
23
24 function CreateObject($class_type)
25 {
26 switch ($class_type) {
27 case "foo":
28 $obj = new MyFoo();  
29 休憩;  
30 case "バー":
31 $obj = new MyBar();  
32 休憩;  
33 }
34 $obj を返す;  
35 }
36
37 $global_obj = CreateObject ("foo");  
38 $global_obj->setValue(7);  
39
40 「値は 」 を印刷します。 $global_obj->getValue() 。 「ん」;  
41 print 「値は 」 。 $global_obj->getValueFromMe() 。 「ん」;  

まず、MyFoo クラスで $this->me を参照し、
他の 3 つのメンバー関数を使用します。1 つは this-> 値を返します。 this->value の値、もう 1 つは this->value->me の値を返しますが、 --$this と MyFoo:: は同じものではありませんか? getValueFromMe() も同じですか?
まず、MyFoo 型のオブジェクトを返す CreateObject("foo") を呼び出します。次に、MyFoo::setValue(7) と MyFoo を呼び出します。 ::getValueFromMe() は、戻り値 7 を取得することを期待します。
もちろん、すべてのケースで 7 を取得した場合、上記の例はこの本の中で最も意味のない例ではないことはご想像いただけると思います。 7 が 2 つもありません。
しかし、どのような結果が得られるのでしょうか。さらに重要なのは、なぜでしょうか。
得られる結果は 7 と 5 です。その理由については、3 つが良いです
まず、その理由を見てください。コンストラクター内では、this と this->me の間の参照が確立されますが、コンストラクターが終了すると、これは同じものになります。 PHP はオブジェクト (new MyFoo の結果、28 行目) を再作成し、それを $obj に割り当てます。他のデータ型と同様に、オブジェクトは特殊化されていないため、X を Y に割り当てることは、Y が Still ポイントのコピーであることを意味します。元のオブジェクト - これで、obj->me は同じものではなくなりました - 1 つを変更しても、もう 1 つは変更されません
上記が最初の理由と同様の理由です。奇跡的に、オブジェクトのインスタンス化の問題 (28 行目) は克服されます。CreateObject によって返された値を global_object に代入すると、依然として同じ問題に遭遇します。global_object は戻り値のコピーになり、再び global_object とglobal_object->me は同じではなくなります。これが 2 番目の理由です
しかし、実際にはそこまではできません。CreateObject が $obj を返したら、これが参照を破棄します (行 34)。 3 番目の理由: では、これを修正するにはどうすればよいでしょうか? 1 つは、例 6.22 (行 24、28、31、37) のように、あらゆる場所にアンパサンドを追加することです。上記のことはすべて忘れてください。PHP5 がこれらの問題をどのように考慮するかを知りたい場合は、
リスト 6.22 PHP 4 の WTMA 症候群 PHP4 WTMA 症候群

コードをコピーします。は次のとおりです:
1 クラス MyFoo {
2 関数 MyFoo()
3 {
4 $this->me = &$this;  
5 $this->value = 2;  
6 }
7
8 関数 setValue($val)
9 {
10 $this->value = $val;  
11 }
12
13 関数getValue()
14 {
15 return $this->value;  
16 }
17
18 関数getValueFromMe()
19 {
20 return $this->me->value;  
21 }
22 };  
23
24 関数 &CreateObject($class_type)
25 {
26 switch ($class_type) {
27 case "foo":
28 $obj =& new MyFoo();  
29 休憩;  
30 case "バー":
31 $obj =& new MyBar();  
32 休憩;  
33 }
34 $obj を返す;  
35 }
36
37 $global_obj =& CreateObject ("foo");  
38 $global_obj->setValue(7);  
39
40 「値は 」 を印刷します。 $global_obj->getValue() 。 「ん」;  
41 print 「値は 」 。 $global_obj->getValueFromMe() 。 「ん」;  

PHP5 は、オブジェクトを他のタイプのデータとは異なる方法で扱う最初の PHP バージョンです。ユーザーの観点から見ると、これは非常に明らかです。PHP5 では、他のタイプのデータ (整数、文字列など) は常に参照によって渡されます。 、配列) はすべて値によって渡されます。最も注目すべき点は、オブジェクトを参照によって渡すことを示すために & 記号を使用する必要がないことです。
オブジェクト指向プログラミングでは、オブジェクト ネットワークとオブジェクト間の複雑な関係がすべて使用されます。以前のバージョンの PHP では、参照を明示的に指定する必要がありました。そのため、オブジェクトは明示的にコピーが要求された場合にのみコピーされるようになり、以前よりも改善されました。
PHP5 より前では、すべての値は zval (Zend Value) と呼ばれる特別な構造体に格納されていました。これらの値は、数値や文字列などの単純な値、または配列や配列などの複雑な値に格納できます。オブジェクト。値が関数に渡されるとき、または関数から返されるとき、これらの値はコピーされ、メモリ内の別のアドレスに同じ内容の構造体が作成されます。PHP5 では、値は zval 構造体に格納されます。オブジェクトはオブジェクトストアと呼ばれる構造体に存在し、それぞれのオブジェクトは異なるIDを持ちます。Zvalではオブジェクトそのものは格納されませんが、オブジェクトを保持するzval構造体をコピーする際にオブジェクトのポインタが格納されます。たとえば、オブジェクトは関数にパラメータとして渡されます。もうデータはコピーされません。同じオブジェクト ポインタを保持し、この特定のオブジェクトが別の zval を通じてポイントしていることをオブジェクト ストアに通知します。この追加の間接指定により、透過的かつ効率的な方法で、PHP オブジェクトが常に参照によって渡されているかのように見えます。
PHP5 では、例 6.21 に戻りますが、コンストラクターで参照を保持するときに、すべてのアンパサンドを除いてすべて正常に動作します (4 行目)。


http://www.bkjia.com/PHPjc/316925.html

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/316925.html技術記事 /* +---------------------------------------------- --- ---------------------------------+ |=この記事は、CorePHP プログラミングの ClassesandObjects の章からの Haohappy のメモです。 |=|= メイン + 個人的な翻訳...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。