Inhaltsverzeichnis
深入PHP内核之面向对象总结,php内核面向对象
一、PHP中创建一个类
二、zend_class_entry结构
二、访问控制
三、申明和更新类中的属性
四、一些其它的宏
五、PHP_METHOD
六、zend_arg_info
七、定义一个类
1、申明
2、添加方法
3、PHP_MINIT_FUNCTION中初始化
4、定义参数
5、具体方法
 6、在PHP中访问
Heim Backend-Entwicklung PHP-Tutorial 深入PHP内核之面向对象总结,php内核面向对象_PHP教程

深入PHP内核之面向对象总结,php内核面向对象_PHP教程

Jul 12, 2016 am 09:00 AM
php eins Kernel 创建 对象 总结 geh tief 面向

深入PHP内核之面向对象总结,php内核面向对象

一、PHP中创建一个类

在PHP中创建一个简单的类是这样的:

<?php
	$obj = new test($url));
?>
Nach dem Login kopieren

二、zend_class_entry结构

zend_class_entry是内核中定义的一个结构体,是PHP中类与对象的基础结构类型。

struct _zend_class_entry {
        char type;
        char *name;
        zend_uint name_length;
        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 *static_members;
        HashTable constants_table;
        struct _zend_function_entry *builtin_functions;

        union _zend_function *constructor;
        union _zend_function *destructor;
        union _zend_function *clone;
        union _zend_function *_ _get;
        union _zend_function *_ _set;
        union _zend_function *_ _call;

        zend_class_iterator_funcs iterator_funcs;

        /* handlers */
        zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC);
        zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object TSRMLS_DC);
        int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type 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;
};
Nach dem Login kopieren

二、访问控制

//fn_flags代表可以在定义方法时使用,zend_property_info.flags代表可以在定义属性时使用,ce_flags代表在定义zend_class_entry时候可用
//ZEND_ACC_CTOR 构造函数掩码 , ZEND_ACC_DTOR  析构函数掩码
//ZEND_ACC_STATIC static函数掩码
//ZEND_ACC_ABSTRACT abstract函数掩码

#define ZEND_ACC_STATIC                     0x01     /* fn_flags, zend_property_info.flags */
#define ZEND_ACC_ABSTRACT                   0x02     /* fn_flags */
#define ZEND_ACC_FINAL                      0x04     /* fn_flags */
#define ZEND_ACC_IMPLEMENTED_ABSTRACT       0x08     /* fn_flags */
#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS    0x10     /* ce_flags */
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS    0x20     /* ce_flags */
#define ZEND_ACC_FINAL_CLASS                0x40     /* ce_flags */
#define ZEND_ACC_INTERFACE                  0x80     /* ce_flags */
#define ZEND_ACC_INTERACTIVE                0x10     /* fn_flags */
#define ZEND_ACC_PUBLIC                     0x100    /* fn_flags, zend_property_info.flags */
#define ZEND_ACC_PROTECTED                  0x200    /* fn_flags, zend_property_info.flags */
#define ZEND_ACC_PRIVATE                    0x400    /* fn_flags, zend_property_info.flags */
#define ZEND_ACC_PPP_MASK   (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE)
#define ZEND_ACC_CHANGED                    0x800    /* fn_flags, zend_property_info.flags */
#define ZEND_ACC_IMPLICIT_PUBLIC            0x1000   /* zend_property_info.flags; unused (1) */
#define ZEND_ACC_CTOR                       0x2000   /* fn_flags */      
#define ZEND_ACC_DTOR                       0x4000   /* fn_flags */     
#define ZEND_ACC_CLONE                      0x8000   /* fn_flags */
#define ZEND_ACC_ALLOW_STATIC               0x10000  /* fn_flags */
#define ZEND_ACC_SHADOW                     0x20000  /* fn_flags */
#define ZEND_ACC_DEPRECATED                 0x40000  /* fn_flags */
#define ZEND_ACC_CLOSURE                    0x100000 /* fn_flags */
#define ZEND_ACC_CALL_VIA_HANDLER           0x200000 /* fn_flags */
Nach dem Login kopieren

三、申明和更新类中的属性

ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value TSRMLS_DC);  
ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length TSRMLS_DC);  
ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, const char *name, size_t name_length, long value TSRMLS_DC);  
ZEND_API int zend_declare_class_constant_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_bool value TSRMLS_DC);  
ZEND_API int zend_declare_class_constant_double(zend_class_entry *ce, const char *name, size_t name_length, double value TSRMLS_DC);  
ZEND_API int zend_declare_class_constant_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_length TSRMLS_DC);  
ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value TSRMLS_DC); 

ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, char *name, int name_length TSRMLS_DC);
ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC);
ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC);
ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, char *name, int name_length, double value TSRMLS_DC);
ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, char *name, int name_length, const char *value TSRMLS_DC);
ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, char *name, int name_length, const char *value, int value_length TSRMLS_DC);

ZEND_API int zend_update_static_property_null(zend_class_entry *scope, char *name, int name_length TSRMLS_DC);
ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC);
ZEND_API int zend_update_static_property_long(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC);
ZEND_API int zend_update_static_property_double(zend_class_entry *scope, char *name, int name_length, double value TSRMLS_DC);
ZEND_API int zend_update_static_property_string(zend_class_entry *scope, char *name, int name_length, const char *value TSRMLS_DC);
ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, char *name, int name_length, const char *value, int value_length TSRMLS_DC);
Nach dem Login kopieren

动态添加属性

#define add_property_long(__arg, __key, __n) add_property_long_ex(__arg, __key, strlen(__key)+1, __n TSRMLS_CC)
#define add_property_null(__arg, __key) add_property_null_ex(__arg, __key, strlen(__key) + 1 TSRMLS_CC)
#define add_property_bool(__arg, __key, __b) add_property_bool_ex(__arg, __key, strlen(__key)+1, __b TSRMLS_CC)
#define add_property_resource(__arg, __key, __r) add_property_resource_ex(__arg, __key, strlen(__key)+1, __r TSRMLS_CC)
#define add_property_double(__arg, __key, __d) add_property_double_ex(__arg, __key, strlen(__key)+1, __d TSRMLS_CC)
#define add_property_string(__arg, __key, __str, __duplicate) add_property_string_ex(__arg, __key, strlen(__key)+1, __str, __duplicate TSRMLS_CC)
#define add_property_stringl(__arg, __key, __str, __length, __duplicate) add_property_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __duplicate TSRMLS_CC)
#define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key)+1, __value TSRMLS_CC)
Nach dem Login kopieren

四、一些其它的宏

#define INIT_CLASS_ENTRY(class_container, class_name, functions) INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, NULL, NULL, NULL)

#define INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset)  INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, sizeof(class_name)-1, functions, handle_fcall, handle_propget, handle_propset, NULL, NULL)

define INIT_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions) INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions, NULL, NULL, NULL, NULL, NULL)

define INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) {           
    const char *cl_name = class_name;       
    int _len = class_name_len;              
    class_container.name = zend_new_interned_string(cl_name, _len+1, 0 TSRMLS_CC);
    if (class_container.name == cl_name) {  
        class_container.name = zend_strndup(cl_name, _len);
    }                                       
    class_container.name_length = _len; 
    INIT_CLASS_ENTRY_INIT_METHODS(class_container, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \
}

#define INIT_CLASS_ENTRY_INIT_METHODS(class_container, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) {                               
    class_container.constructor = NULL; 
    class_container.destructor = NULL;      
    class_container.clone = NULL;           
    class_container.serialize = NULL;       
    class_container.unserialize = NULL; 
    class_container.create_object = NULL;   
    class_container.interface_gets_implemented = NULL;
    class_container.get_static_method = NULL;
    class_container.__call = handle_fcall;  
    class_container.__callstatic = NULL;    
    class_container.__tostring = NULL;      
    class_container.__get = handle_propget;
    class_container.__set = handle_propset;
    class_container.__unset = handle_propunset;
    class_container.__isset = handle_propisset;
    class_container.serialize_func = NULL;  
    class_container.unserialize_func = NULL;
    class_container.serialize = NULL;       
    class_container.unserialize = NULL; 
    class_container.parent = NULL;          
    class_container.num_interfaces = 0; 
    class_container.traits = NULL;          
    class_container.num_traits = 0;         
    class_container.trait_aliases = NULL;   
    class_container.trait_precedences = NULL;
    class_container.interfaces = NULL;      
    class_container.get_iterator = NULL;    
    class_container.iterator_funcs.funcs = NULL;
    class_container.info.internal.module = NULL;
    class_container.info.internal.builtin_functions = functions;
}
Nach dem Login kopieren

五、PHP_METHOD

PHP_METHOD(test,__construct);
PHP_METHOD(test,__destruct);
PHP_METHOD(test,setproperty);
PHP_METHOD(test,getproperty);
Nach dem Login kopieren

内核中的定义

#define PHP_METHOD  ZEND_METHOD
#define ZEND_METHOD(classname, name)   ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v    alue_used TSRMLS_DC

//等价于
void name(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v    alue_used TSRMLS_DC )
Nach dem Login kopieren

六、zend_arg_info

typedef struct _zend_arg_info {
    const char *name; //参数名称
    zend_uint name_len;//长度
    const char *class_name;  //所属类名
    zend_uint class_name_len;  //类名长度
    zend_bool array_type_hint;
    zend_bool allow_null; //允许为空
    zend_bool pass_by_reference;  //引用传值
    zend_bool return_reference;   //引用返回
    int required_num_args;   //参数个数
} zend_arg_info;
Nach dem Login kopieren

接受参数.那么就要执行 

ZEND_BEGIN_ARG_INFO(test___construct_arginfo, 0)
    ZEND_ARG_INFO(0, url)
ZEND_END_ARG_INFO()
Nach dem Login kopieren
Nach dem Login kopieren

ZEND_BEGIN_ARG_INFO_EX定义在Zend/zend_API.h

define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args)       \
    static const zend_arg_info name[] = {                                                                                                                                           \
        { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
Nach dem Login kopieren

ZEND_ARG_INFO(0,url)的定义如下

#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
Nach dem Login kopieren

最终是这样的

static const zend_arg_info name[] = {
	{ NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
	{ #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
};
Nach dem Login kopieren

七、定义一个类

1、申明

static zend_class_entry *test_ce;
Nach dem Login kopieren

2、添加方法

const zend_function_entry test_methods[] = {
    PHP_ME(test, __construct, test___construct_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) 
    PHP_ME(test, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR)
    PHP_ME(test, __toString, NULL, ZEND_ACC_PUBLIC)
    PHP_ME(test, getMeta, NULL, ZEND_ACC_PUBLIC)
    PHP_ME(test, setMeta, NULL, ZEND_ACC_PUBLIC)
    { NULL, NULL, NULL }
};

//ZEND_ACC_CTOR标示构造函数
//ZEND_ACC_DTOR标示析构函数
Nach dem Login kopieren

3、PHP_MINIT_FUNCTION中初始化

PHP_MINIT_FUNCTION(test)
{
    /*定义一个temp class*/
    zend_class_entry ce;

    /*初始化这个class,第二个参数是class name, 第三个参数是class methods*/
    INIT_CLASS_ENTRY(ce, "test", test_methods);

    /*注册这个class到zend engine*/
    test_ce = zend_register_internal_class(&ce TSRMLS_CC);

    return SUCCESS;
}
Nach dem Login kopieren

4、定义参数

ZEND_BEGIN_ARG_INFO(test___construct_arginfo, 0)
    ZEND_ARG_INFO(0, url)
ZEND_END_ARG_INFO()
Nach dem Login kopieren
Nach dem Login kopieren

5、具体方法

static PHP_METHOD(test, __construct) {
    char *url;
    int url_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &url, &url_len, &age) == FAILURE) {
        return;
    }

    zval *obj;
    obj = getThis();

    zend_update_property_stringl(test_ce, obj, "url", sizeof("url") -1, url, url_len TSRMLS_CC);
}
Nach dem Login kopieren

6、在PHP中访问

<?php
    $c = new test('http://test.com');
?>
Nach dem Login kopieren

 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1093864.htmlTechArticle深入PHP内核之面向对象总结,php内核面向对象 一、PHP中创建一个类 在PHP中创建一个简单的类是这样的: ?php$obj = new test($url));? 二、zend_cl...
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat -Befehle und wie man sie benutzt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

PHP 8.4 Installations- und Upgrade-Anleitung für Ubuntu und Debian PHP 8.4 Installations- und Upgrade-Anleitung für Ubuntu und Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 bringt mehrere neue Funktionen, Sicherheitsverbesserungen und Leistungsverbesserungen mit einer beträchtlichen Menge an veralteten und entfernten Funktionen. In dieser Anleitung wird erklärt, wie Sie PHP 8.4 installieren oder auf PHP 8.4 auf Ubuntu, Debian oder deren Derivaten aktualisieren. Obwohl es möglich ist, PHP aus dem Quellcode zu kompilieren, ist die Installation aus einem APT-Repository wie unten erläutert oft schneller und sicherer, da diese Repositorys in Zukunft die neuesten Fehlerbehebungen und Sicherheitsupdates bereitstellen.

So richten Sie Visual Studio-Code (VS-Code) für die PHP-Entwicklung ein So richten Sie Visual Studio-Code (VS-Code) für die PHP-Entwicklung ein Dec 20, 2024 am 11:31 AM

Visual Studio Code, auch bekannt als VS Code, ist ein kostenloser Quellcode-Editor – oder eine integrierte Entwicklungsumgebung (IDE) –, die für alle gängigen Betriebssysteme verfügbar ist. Mit einer großen Sammlung von Erweiterungen für viele Programmiersprachen kann VS Code c

7 PHP-Funktionen, die ich leider vorher nicht kannte 7 PHP-Funktionen, die ich leider vorher nicht kannte Nov 13, 2024 am 09:42 AM

Wenn Sie ein erfahrener PHP-Entwickler sind, haben Sie möglicherweise das Gefühl, dass Sie dort waren und dies bereits getan haben. Sie haben eine beträchtliche Anzahl von Anwendungen entwickelt, Millionen von Codezeilen debuggt und eine Reihe von Skripten optimiert, um op zu erreichen

Wie analysiert und verarbeitet man HTML/XML in PHP? Wie analysiert und verarbeitet man HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

Dieses Tutorial zeigt, wie XML -Dokumente mit PHP effizient verarbeitet werden. XML (Extensible Markup-Sprache) ist eine vielseitige textbasierte Markup-Sprache, die sowohl für die Lesbarkeit des Menschen als auch für die Analyse von Maschinen entwickelt wurde. Es wird üblicherweise für die Datenspeicherung ein verwendet und wird häufig verwendet

Erklären Sie JSON Web Tokens (JWT) und ihren Anwendungsfall in PHP -APIs. Erklären Sie JSON Web Tokens (JWT) und ihren Anwendungsfall in PHP -APIs. Apr 05, 2025 am 12:04 AM

JWT ist ein offener Standard, der auf JSON basiert und zur sicheren Übertragung von Informationen zwischen Parteien verwendet wird, hauptsächlich für die Identitätsauthentifizierung und den Informationsaustausch. 1. JWT besteht aus drei Teilen: Header, Nutzlast und Signatur. 2. Das Arbeitsprinzip von JWT enthält drei Schritte: Generierung von JWT, Überprüfung von JWT und Parsingnayload. 3. Bei Verwendung von JWT zur Authentifizierung in PHP kann JWT generiert und überprüft werden, und die Funktionen und Berechtigungsinformationen der Benutzer können in die erweiterte Verwendung aufgenommen werden. 4. Häufige Fehler sind Signaturüberprüfungsfehler, Token -Ablauf und übergroße Nutzlast. Zu Debugging -Fähigkeiten gehört die Verwendung von Debugging -Tools und Protokollierung. 5. Leistungsoptimierung und Best Practices umfassen die Verwendung geeigneter Signaturalgorithmen, das Einstellen von Gültigkeitsperioden angemessen.

PHP -Programm zum Zählen von Vokalen in einer Zeichenfolge PHP -Programm zum Zählen von Vokalen in einer Zeichenfolge Feb 07, 2025 pm 12:12 PM

Eine Zeichenfolge ist eine Folge von Zeichen, einschließlich Buchstaben, Zahlen und Symbolen. In diesem Tutorial wird lernen, wie Sie die Anzahl der Vokale in einer bestimmten Zeichenfolge in PHP unter Verwendung verschiedener Methoden berechnen. Die Vokale auf Englisch sind a, e, i, o, u und sie können Großbuchstaben oder Kleinbuchstaben sein. Was ist ein Vokal? Vokale sind alphabetische Zeichen, die eine spezifische Aussprache darstellen. Es gibt fünf Vokale in Englisch, einschließlich Großbuchstaben und Kleinbuchstaben: a, e, ich, o, u Beispiel 1 Eingabe: String = "TutorialPoint" Ausgabe: 6 erklären Die Vokale in der String "TutorialPoint" sind u, o, i, a, o, ich. Insgesamt gibt es 6 Yuan

Erklären Sie die späte statische Bindung in PHP (statisch: :). Erklären Sie die späte statische Bindung in PHP (statisch: :). Apr 03, 2025 am 12:04 AM

Statische Bindung (statisch: :) implementiert die späte statische Bindung (LSB) in PHP, sodass das Aufrufen von Klassen in statischen Kontexten anstatt Klassen zu definieren. 1) Der Analyseprozess wird zur Laufzeit durchgeführt.

Was sind PHP Magic -Methoden (__construct, __Destruct, __call, __get, __set usw.) und geben Sie Anwendungsfälle an? Was sind PHP Magic -Methoden (__construct, __Destruct, __call, __get, __set usw.) und geben Sie Anwendungsfälle an? Apr 03, 2025 am 12:03 AM

Was sind die magischen Methoden von PHP? Zu den magischen Methoden von PHP gehören: 1. \ _ \ _ Konstrukt, verwendet, um Objekte zu initialisieren; 2. \ _ \ _ Destruct, verwendet zur Reinigung von Ressourcen; 3. \ _ \ _ Call, behandeln Sie nicht existierende Methodenaufrufe; 4. \ _ \ _ GET, Implementieren Sie den dynamischen Attributzugriff; 5. \ _ \ _ Setzen Sie dynamische Attributeinstellungen. Diese Methoden werden in bestimmten Situationen automatisch aufgerufen, wodurch die Code -Flexibilität und -Effizienz verbessert werden.

See all articles