私が初めて PHP に触れたとき、私はプロセス指向のアプローチを使って、非常に単純な Web サイトをいくつか作成していました。PHP コードを書くのは単なる積み重ねであり、スケーラビリティと保守性は非常に悪かったです。ロジックを変更するのは困難です。その後、PHP がオブジェクト指向をサポートしていることを知り、結局のところ、PHP は C で実装されているのですが、これは驚くべきことではありません。
まえがき:
PHPに出会った時から、私たちが最初に出会ったのは、配列操作関数、文字列操作関数、ファイル操作関数、等 これらの関数は、PHP を使用するための基礎であり、PHP が誕生以来サポートしてきたプロセス指向のプログラミングでもあります。プロセス指向では、機能を 1 つずつカプセル化し、モジュール的な考え方で問題を解決します。
PHP4 以降のオブジェクト指向プログラミングをサポートします。ただし、PHP4 のオブジェクト指向サポートは完全ではありません。 PHP5 以降、PHP は新しいオブジェクト モデル (オブジェクト モデル) を導入し、アクセス制御、抽象クラスと最終クラス、クラス メソッド、マジック メソッド、インターフェイス、オブジェクトの複製、型ヒントなどを含む多くの新機能を追加しました。 そして、最近リリースされたバージョンの PHP5.3 では、オブジェクト指向プログラミングのために、名前空間、遅延静的バインディング、そして 2 つのマジック メソッド __callStatic() と __invoke() が追加されました。
では、PHP の下部ではどのように実装され、どのような構造になっているのでしょうか?
1つ。クラス構造
TIPI の引用例:
class ParentClass { } interface Ifce { public function iMethod(); } final class Tipi extends ParentClass implements Ifce { public static $sa = 'aaa'; const CA = 'bbb'; public function __constrct() { } public function iMethod() { } private function _access() { } public static function access() { } }
ここでは、親クラス ParentClass、インターフェース Ifce、サブクラス Tipi が定義されています。サブクラスは親クラス ParentClass を継承し、インターフェイス Ifce を実装し、静的変数 $sa、クラス定数 CA、パブリック メソッド、プライベート メソッド、およびパブリック スタティック メソッドを持ちます。 これらの構造は Zend エンジン内でどのように実装されているのでしょうか?クラスメソッドとメンバー変数はどのように保存されますか?アクセス制御、静的メンバーはどのようにマークされますか?
まず、クラスの内部ストレージ構造を見てみましょう:
上記の構造のいくつかのフィールドを使用して、カーネル内の記事の冒頭にある PHP コードのパフォーマンスを分析します。 以下に示すように:
フィールド名 | フィールドの説明 | ParentClassクラス | Ifceインターフェース | Tipiクラス |
name | クラス名 | ParentClass | Ifce | ティピ |
タイプ | カテゴリ | 2 (ユーザー定義) | 2 (ユーザー定義) | 2 (ユーザー定義、1 はシステム組み込みクラス) |
parent | 親クラス | empty | empty | ParentClassクラス |
refcount | 参照数 | 1 | 1 | 2 |
ce_flags | クラスの種類 | 0 | 144 | 524352 |
function_table | function list | empty | function_name | =iメソッド=258 | 関数名=__construct | fn_flags=8448関数名=_アクセス |Function_name = アクセス | タイプ = 2 | Fn_flags = 257 |
インターフェース | インターフェースリスト | 空の | FCE インターフェースインターフェースは 1 | |
/tipi.php | / ipi.php | line_start | ||
15 | 18 | 22 | line_end | |
16 | 20 | 38 | 二。变量与成员变量 如PHP内核的存储机制(分离/改变)所介绍, 变量要么是定义在全局范围中,叫做全局变量,要么是定义在某个函数中, 叫做局部变量。 成员变量是定义在类里面,并和成员方法处于同一层次。如下一个简单的PHP代码示例,定义了一个类, 并且这个类有一个成员变量。 class Tipi { public $var; } ログイン後にコピー 1.成员变量的访问: 访问这个成员变量当然是通过对象来访问。 2.成员变量的规则:
在声明类的时候初始化了类的成员变量所在的HashTable,之后如果有新的成员变量声明时,在编译时zend_do_declare_property。函数首先检查成员变量不允许的这4 条情况。 比如:. class Tipi { public final $var; } ログイン後にコピー 运行程序将报错,违反了第三条:Fatal error: Cannot declare property Tipi::$var final, the final modifier is allowed only for methods and classes in .. 这个错误由zend_do_declare_property函数抛出 三。函数与成员方法 成员方法从本质上来讲也是一种函数,所以其存储结构也和常规函数一样,存储在zend_function结构体中。 对于一个类的多个成员方法,它是以HashTable的数据结构存储了多个zend_function结构体。 和前面的成员变量一样,在类声明时成员方法也通过调用zend_initialize_class_data方法,初始化了整个方法列表所在的HashTable。 在类中我们如果要定义一个成员方法,格式如下: class Tipi{ public function t() {echo 1; } } ログイン後にコピー 除去访问控制关键字,一个成员方法和常规函数是一样的,从语法解析中调用的函数一样(都是zend_do_begin_function_declaration函数), 但是其调用的参数有一些不同,第三个参数is_method,成员方法的赋值为1,表示它作为成员方法的属性。 在这个函数中会有一系统的编译判断,比如在接口中不能声明私有的成员方法。 看这样一段代码: interface Ifce { private function method(); } ログイン後にコピー 直接実行すると、プログラムはエラーを報告します: 致命的エラー: インターフェースメソッド Ifce::method() のアクセスタイプは省略されなければなりません このコードは、zend_do_begin_function_declaration 関数のコードに対応します。 4つ。メソッドとメソッドの類似点と相違点 関数とメソッドの実装については、どちらも実行用のコレクションに比較的似ています。使用上の 2 つの違いについては、ここで 2 つの実装について説明します。 実装の観点から見ると、両方の内部コードは最終的に op_array として解釈され、その実行には違いはありません (オブジェクト固有の変更や $this/self などのメソッドが使用されない限り)。 2 つのアスペクトに反映されています:
PHP 呼び出しメソッドの実装
定義の場所と性質の違いにより、メソッドには関数よりも多くの検証作業が必要であり、メソッド呼び出しにはより多くの検証作業が必要であることが決まります関数以外に、 ZEND_INIT_METHOD_CALL 、 という名前の追加のOPCODEがあり、その関数は関数と同じ処理関数を使用できます。 ZEND_DO_FCALL_BY_N AME 以上がPHPコア - クラスとオブジェクト指向コードの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
最新の問題
テーブル tr:first-child td の機能上の問題
CSS とテーブルを使用して、分子と分母の間に分数線を配置します。複素分数の場合、Ant ブラウザでは正しく動作しません。以下は、この問題を示す Tryit エディターで使用される...
から 2024-03-30 13:24:05
0
1
295
関連トピック
詳細>
|