Inhaltsverzeichnis
[转]自己写PHP扩展之创建一个类,php一个类
Heim php教程 php手册 [转]自己写PHP扩展之创建一个类,php一个类

[转]自己写PHP扩展之创建一个类,php一个类

Jun 13, 2016 am 08:40 AM
函数调用

[转]自己写PHP扩展之创建一个类,php一个类

原文:http://www.imsiren.com/archives/572

比如我们要创建一个类..PHP代码如下

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Person {     public $name;     public $age;     public function __construct() {         echo "construct is running! ";     }     public function __destruct() {         echo " destruct is running!";     }     public function getproperty($key) {         echo $this->$key;     }     public function setproperty($key,$val) {         $this->$key = $val;     } }

用PHP来做,很简单..
那么用PHP扩展来写该怎么做?
OK.
1.在php_siren.h里面声明类

1 2 3 4 PHP_METHOD(Person,__construct); PHP_METHOD(Person,__destruct); PHP_METHOD(Person,setproperty); PHP_METHOD(Person,getproperty);

PHP_METHOD宏.
PHP_METHOD 等于ZEND_METHOD
这个宏接受两个参数,第一个是类名,第二个是类的方法

1 2 3 4 #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 )

这个宏是用来声明我们的方法…
2.设置接收的参数
我们的方法如果需要接受参数.那么就要执行

1 2 3 ZEND_BEGIN_ARG_INFO_EX(arg_person_info,0,0,2)         ZEND_ARG_INFO(0,name) ZEND_END_ARG_INFO()

详细讲这几个宏之前先看看zend_arg_info

1 2 3 4 5 6 7 8 9 10 11 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;

ZEND_BEGIN_ARG_INFO_EX定义在Zend/zend_API.h

1 2 3 #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 },

很明显 声明一个zend_arg_info的数组name,然后初始化结构体的值
ZEND_ARG_INFO(0,name)的定义如下

1 #define ZEND_ARG_INFO(pass_by_ref, name)  { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },

这三个宏 执行代码 等于

1 2 3 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 }, };

3.创建zend_function_entry结构数组

1 2 3 4 5 6 7 const zend_function_entry person_functions[]={         PHP_ME(Person,__construct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)         PHP_ME(Person,__destruct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)         PHP_ME(Person,getproperty,arg_person_info,ZEND_ACC_PUBLIC)         PHP_ME(Person,setproperty,arg_person_info,ZEND_ACC_PUBLIC)         PHP_FE_END };

zend_function_entry定义如下

1 2 3 4 5 6 7 typedef struct _zend_function_entry {         const char *fname; //函数名称         void (*handler)(INTERNAL_FUNCTION_PARAMETERS);         const struct _zend_arg_info *arg_info;//参数         zend_uint num_args;//参数个数         zend_uint flags;//标示PUBLIC ?PRIVATE ?PROTECTED } zend_function_entry;

PHP_ME宏接收四个参数
1 类名,
2 方法名,
3 zend_arg_info 的参数列表,

ZEND_ACC_PUBLIC ZEND_ACC_PRIVATE ZEND_ACC_PROTECTED是我们类里面的三个访问权限
ZEND_ACC_CTOR标示构造函数
ZEND_ACC_DTOR标示析构函数
4.修改PHP_MINIT_FUNCTION
前面我们说过 PHP_MINIT_FUNCTION是在模块启动的时候执行的函数
首先创建一个全局指针 zend_class_entry *person_ce;
在PHP_MINIT_FUNCTION加入如下代码

1 2 3 4 zend_class_entry person; INIT_CLASS_ENTRY(person,"Person",person_functions); person_ce=zend_register_internal_class_ex(&person,NULL,NULL TSRMLS_CC); zend_declare_property_null(person_ce,ZEND_STRL("name"),ZEND_ACC_PUBLIC TSRMLS_CC);

1行创建一个zend_class_entry对象person.
zend_class_entry这个结构体前面也讲过 PHP内核研究之类的实现
2行初始化zend_class_entry 它执行了如下代码

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 {                                                                                                                       \         int _len = class_name_len;                                                              \         class_container.name = zend_strndup(class_name, _len);  \         class_container.name_length = _len;                                             \         class_container.builtin_functions = functions;                  \         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.interfaces = NULL;                                              \         class_container.get_iterator = NULL;                                    \         class_container.iterator_funcs.funcs = NULL;                    \         class_container.module = NULL;                                                  \ }

可以对应文章>> PHP内核研究之类的实现来分析
zend_declare_property_null(person_ce,ZEND_STRL(“name”),ZEND_ACC_PUBLIC TSRMLS_CC);
创建一个值为NULL的属性
第一个参数是类名,第二个参数是 属性名称,第三个参数是属性名的长度,因为ZEND_STRL宏定义了长度,所以这里不用再传递长度.
第四个参数是属性的访问权限.
还有其他几个函数用来创建不同类型的属性

1 2 3 4 5 6 7 zend_declare_property_bool zend_declare_property_double zend_declare_property_ex zend_declare_property_long zend_declare_property_null zend_declare_property_string zend_declare_property_stringl

5.创建 php_siren.h头文件中的方法体

1 2 3 4 5 6 7 8 9 10 11 12 PHP_METHOD(Person,__construct){         php_printf("construct is running
"
); } PHP_METHOD(Person,__destruct){         php_printf("destruct is running
"
); } PHP_METHOD(Person,setproperty){   } PHP_METHOD(Person,getproperty){   }

6.最后make&& make install
编译我们的扩展,
重新启动apache.
$p=new Person();
?>
我们就能在浏览器里看到输出的内容

construct is running
destruct is running

这样 ..我们用扩展创建的一个基本类就完成了.

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)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
3 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)

Leistungsoptimierung von C++-Funktionsaufrufen: Auswirkungen der Parameterübergabe und Rückgabewerte Leistungsoptimierung von C++-Funktionsaufrufen: Auswirkungen der Parameterübergabe und Rückgabewerte May 04, 2024 pm 12:57 PM

Die Leistungsoptimierung von C++-Funktionsaufrufen umfasst zwei Aspekte: Parameterübergabestrategie und Optimierung des Rückgabewerttyps. In Bezug auf die Parameterübergabe eignet sich die Übergabe von Werten für kleine Objekte und nicht veränderbare Parameter, während die Übergabe von Referenzen oder Zeigern für große Objekte und veränderbare Parameter geeignet ist und die Übergabe von Zeigern am schnellsten ist. Im Hinblick auf die Optimierung des Rückgabewerts können kleine Werte direkt zurückgegeben werden, und große Objekte sollten Referenzen oder Zeiger zurückgeben. Durch die Wahl der geeigneten Strategie kann die Leistung von Funktionsaufrufen verbessert werden.

Wie rufe ich Funktionen in verschiedenen Modulen in C++ auf? Wie rufe ich Funktionen in verschiedenen Modulen in C++ auf? Apr 12, 2024 pm 03:54 PM

Modulübergreifender Aufruf von Funktionen in C++: Funktion deklarieren: Deklarieren Sie die aufzurufende Funktion in der Header-Datei des Zielmoduls. Funktion implementieren: Implementieren Sie die Funktion in der Quelldatei. Verknüpfen von Modulen: Verwenden Sie einen Linker, um Module miteinander zu verknüpfen, die Funktionsdeklarationen und Implementierungen enthalten. Rufen Sie die Funktion auf: Fügen Sie die Header-Datei des Zielmoduls in das aufzurufende Modul ein und rufen Sie dann die Funktion auf.

C++-Funktionsaufrufreflexionstechnologie: Parameterübergabe und dynamischer Zugriff auf Rückgabewerte C++-Funktionsaufrufreflexionstechnologie: Parameterübergabe und dynamischer Zugriff auf Rückgabewerte May 05, 2024 am 09:48 AM

Die C++-Funktionsaufrufreflexionstechnologie ermöglicht das dynamische Abrufen von Funktionsparametern und Rückgabewertinformationen zur Laufzeit. Verwenden Sie die Ausdrücke typeid(decltype(...)) und decltype(...), um Parameter- und Rückgabewerttypinformationen abzurufen. Durch Reflexion können wir Funktionen dynamisch aufrufen und bestimmte Funktionen basierend auf der Laufzeiteingabe auswählen, was flexiblen und skalierbaren Code ermöglicht.

Entdecken Sie die verschiedenen Möglichkeiten, PHP-Funktionen aufzurufen Entdecken Sie die verschiedenen Möglichkeiten, PHP-Funktionen aufzurufen Apr 16, 2024 pm 02:03 PM

Es gibt fünf Möglichkeiten, PHP-Funktionen aufzurufen: direkter Aufruf, Aufruf über Variable, anonyme Funktion, Funktionszeiger und Reflexion. Indem Sie die Methode auswählen, die am besten zu Ihrer Situation passt, können Sie die Leistung optimieren und die Einfachheit des Codes verbessern.

Detaillierte Erläuterung des C++-Funktionsaufrufmechanismus Detaillierte Erläuterung des C++-Funktionsaufrufmechanismus Apr 11, 2024 pm 02:12 PM

Der Funktionsaufrufmechanismus in C++ umfasst die Übergabe von Argumenten an eine Funktion und die Ausführung ihres Codes sowie die Rückgabe des Ergebnisses, sofern vorhanden. Es gibt zwei Möglichkeiten, Parameter zu übergeben: Übergabe als Wert (Änderungen werden innerhalb der Funktion vorgenommen) und Übergabe als Referenz (Änderungen werden im Aufrufer widergespiegelt). Bei der Wertübergabe wirken sich Wertänderungen innerhalb der Funktion nicht auf den ursprünglichen Wert aus (z. B. printValue), während Änderungen bei der Referenzübergabe den ursprünglichen Wert beeinflussen (z. B. printReference).

Testen von C++-Funktionsaufrufeinheiten: Überprüfung der Korrektheit der Parameterübergabe und des Rückgabewerts Testen von C++-Funktionsaufrufeinheiten: Überprüfung der Korrektheit der Parameterübergabe und des Rückgabewerts May 01, 2024 pm 02:54 PM

Bei der Überprüfung von C++-Funktionsaufrufen im Unit-Test müssen Sie die folgenden zwei Punkte überprüfen: Parameterübergabe: Verwenden Sie Assertionen, um zu überprüfen, ob die tatsächlichen Parameter mit den erwarteten Werten übereinstimmen. Rückgabewert: Verwenden Sie Zusicherungen, um zu prüfen, ob der tatsächliche Rückgabewert dem erwarteten Wert entspricht.

Präprozessormakros für C++-Funktionsaufrufe: Erweiterte Verwendung der Parameterübergabe und Rückgabewerte Präprozessormakros für C++-Funktionsaufrufe: Erweiterte Verwendung der Parameterübergabe und Rückgabewerte May 04, 2024 pm 04:33 PM

In C++ können Präprozessormakros zum Aufrufen von Funktionen verwendet werden, was die folgenden Schritte umfasst: Parameterübergabe: Makroparameter werden in Klammern eingeschlossen und durch Kommas getrennt. Rückgabewert: Mit Makroparametern legen Sie den zurückzugebenden Wert fest und weisen ihn einer Variablen zu. Praktischer Fall: Durch die Verwendung der Makrooptimierung zum Ermitteln der Funktion des Maximalwertindex im Array wird die Anzahl der Berechnungen reduziert und die Effizienz verbessert.

C++-Kompilierungsfehler: Funktionsaufruf stimmt nicht mit Funktionsdeklaration überein, wie kann man ihn lösen? C++-Kompilierungsfehler: Funktionsaufruf stimmt nicht mit Funktionsdeklaration überein, wie kann man ihn lösen? Aug 22, 2023 pm 12:39 PM

C++-Kompilierungsfehler: Funktionsaufruf stimmt nicht mit Funktionsdeklaration überein, wie kann man ihn lösen? Bei der Entwicklung von C++-Programmen treten zwangsläufig einige Kompilierungsfehler auf. Einer der häufigsten Fehler besteht darin, dass der Funktionsaufruf nicht mit der Funktionsdeklaration übereinstimmt. Diese Art von Fehler kommt unter C++-Programmierern häufig vor, da sie nicht auf die Korrektheit der Funktionsdeklaration achten und zu Kompilierungsproblemen führen, was letztendlich Zeit und Energie zur Behebung des Problems verschwendet und die Entwicklungseffizienz beeinträchtigt. Um diesen Fehler zu vermeiden, müssen einige Normen und Standardpraktiken befolgt werden. Schauen wir uns diese unten an. Was ist ein Funktionsaufruf im Vergleich zu einer Funktionsdeklaration?

See all articles