PHPer にとって、OOP は開発の考え方に不可欠ですが、どれだけの効果があるのかPHP クラスとオブジェクトの基礎となる実装についてご存知ですか?何が起こっているのか、なぜそうなのかを知るという考えに基づいて、一緒に答えを見つけましょう~クラスの基礎となる実装は、変数や関数の知識の集合とみなすことができます。など、以前にもお話しました。したがって、より深く理解したい学生は、変数と関数の紹介についての私の以前の記事を参照してください。クラス データ構造通常のクラス、抽象クラス、インターフェイスのいずれであっても、このクラスは統一された構造に格納され、中間コードの生成時にグローバル クラス リストに追加されます。もちろん、このとき、そのクラスが既に存在するかどうかはクラス名で判断しますが、存在する場合は追加に失敗します
struct _zend_class_entry { char type; // 和函数一样,类被拆分为两种类型:ZEND_INTERNAL_CLASS 内部类型和ZEND_USER_CLASS 用户自定义类型 char *name;// 类名称 zend_uint name_length; // 即sizeof(name) - 1 struct _zend_class_entry *parent; // 继承的父类 int refcount; // 引用数 zend_bool constants_updated; zend_uint ce_flags; //类的类型,在编译阶段被区分是普通类,接口,抽象类 HashTable function_table; // 静态类方法和普通类方法存放集合 HashTable default_properties; // 默认属性存放集合 HashTable properties_info; // 属性信息存放集合 HashTable default_static_members;// 类本身所具有的静态变量存放集合 HashTable *static_members; // type == ZEND_USER_CLASS时,取&default_static_members; // type == ZEND_INTERAL_CLASS时,设为NULL HashTable constants_table; // 常量存放集合 struct _zend_function_entry *builtin_functions;// 方法定义入口 /* 魔术方法 */ //所有魔术方法单独存放,初始化时被设置为null union _zend_function *constructor; union _zend_function *destructor; union _zend_function *clone; union _zend_function *__get; union _zend_function *__set; union _zend_function *__unset; union _zend_function *__isset; union _zend_function *__call; union _zend_function *__tostring; union _zend_function *serialize_func; union _zend_function *unserialize_func; zend_class_iterator_funcs iterator_funcs;// 迭代 /* 类句柄 */ zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC); zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, intby_ref TSRMLS_DC); /* 类声明的接口 */ int(*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type TSRMLS_DC); /* 序列化回调函数指针 */ int(*serialize)(zval *object, unsignedchar**buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC); int(*unserialize)(zval **object, zend_class_entry *ce, constunsignedchar*buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC); zend_class_entry **interfaces; // 类实现的接口 zend_uint num_interfaces; // 类实现的接口数 char *filename; // 类的存放文件地址 绝对地址 zend_uint line_start; // 类定义的开始行 zend_uint line_end; // 类定义的结束行 char *doc_comment; zend_uint doc_comment_len; struct _zend_module_entry *module; // 类所在的模块入口:EG(current_module) };上記のコードからも分かるように、メンバ変数とメンバはクラスのメソッドはそれぞれの構造体に格納されます。 構造体のデータ構造は、コンパイルされたメンバー変数とメンバー メソッドがクラス構造体に格納されることを除いて、前に説明した変数や関数のデータ構造とまったく同じです。 オブジェクトの生成 オブジェクトが new によって作成されることは誰もが知っていますが、低レベルの観点から見ると、オブジェクトの生成は 3 つのステップに分かれています
最初のステップ:クラスがクラス名に従ってグローバル クラス リストに存在する場合 存在する場合は、ストレージ クラスの変数を取得します
ステップ 2: クラスが通常のクラス (非抽象クラスまたはインターフェイス) であるかどうかを判断します。は通常のクラスであり、作成するオブジェクトが格納される zval コンテナにメモリを割り当て、IS_OBJECT
のコンテナ タイプを設定します。 ステップ 3: オブジェクトの初期化操作を実行し、オブジェクトをグローバル オブジェクト リスト (オブジェクト プール) に追加します。
typedef struct _zend_object { zend_class_entry *ce; //对象的类结构 HashTable *properties; //对象属性 HashTable *guards; /* protects from __get/__set ... recursion */ } zend_object;メンバー変数の取得と設定メンバー変数の取得:
最初のステップは、オブジェクトのプロパティを取得することです。オブジェクトのプロパティから名前に対応する属性があるかどうかを確認し、存在する場合は結果を返し、存在しない場合は 2 番目のステップに進みます
2 番目のステップは、get マジック メソッドがある場合、このメソッドを呼び出して変数を取得します。変数が存在しない場合は、エラーが報告されます。
最初のステップでは、オブジェクトのプロパティからオブジェクトのプロパティを取得します。名前に対応するプロパティが存在するかどうかを確認します。存在し、既存の値が設定する必要がある値と同じである場合は何も実行されません。そうでない場合は、変数の代入操作が実行されます。存在しない場合は、 2 番目のステップに進みます
ステップ 2 、 _set マジック メソッドが存在する場合は、このメソッドを呼び出して変数を設定します 存在しない場合は、3 番目のステップに進みます
3 番目のステップ、メンバー変数が存在しない場合設定されている場合は、この変数を HashTable にあるオブジェクトのプロパティ フィールドに直接追加します。
PHP 関連の技術記事の詳細については、# をご覧ください。 ##PHP チュートリアル 学ぶべきコラム!
以上がPHP の基礎となる原則、クラス、オブジェクトの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。