PHP extension writing php Extension Writing (Sara golemon) _php Tutorial

Source: Internet
Author: User
Tags echo command php language sapi zts zend
Original: Http://devzone.zend.com/public/view/tag/ExtensionPart i:introduction to PHP and Zend Write extensions i-php and Zend Start/HTTP// Devzone.zend.com/article/1021-extension-writing-part-i-introduction-to-php-and-zendpart Ii:parameters, Arrays, and Zvals write extended _ii-arguments, arrays, and zvalshttp://devzone.zend.com/article/1022- Extension-writing-part-ii-parameters-arrays-and-zvalspart Ii:parameters, Arrays, and Zvals [continued] Write extension _ii-parameters, Arrays and zvals[continue to]http://devzone.zend.com/article/1023- Extension-writing-part-ii-parameters-arrays-and-zvals-continuedpart iii:resources Writing Extension _III-Resources http:/ Devzone.zend.com/article/1024-extension-writing-part-iii-resources
Write Extensions i:php and Zend Start extension tutorials by Sara Golemon | Monday, February 28, 2005
What is an introduction to extensions? Life cycle memory allocation build environment Hello World Build Your Extended initial settings (INI) global numeric initial settings (INI) as global numeric check (code) integrity what's next?
Introduction Since you are reading this tutorial, you may be interested in writing extensions to the PHP language. If not ... Well, maybe you don't know the interest, and you'll find it when we're done. This tutorial assumes that you are basically familiar with the language of the PHP language and its interpreter implementations: C. Let's start by indicating why you want to write a php extension. Limited to the level of abstraction of the PHP language itself, it cannot directly access certain libraries or operating system-specific calls. You want to customize PHP behavior in some unusual way. You have some ready-made PHP code, but you know it can (run) faster, (takes up space) smaller, and consumes less memory. You have some nice code to sell and the buyer can use it, but it is important not to see the source code. These are all very legitimate reasons, but before you create an extension, you need to understand what the extension is. What is an extension? If you've ever used PHP, you've definitely used extensions. With a few exceptions, the functions of each user space are organized into different extensions. Many of these functions are enough to be standard extensions-the total is more than 400. PHP itself has 86 extensions (at the time of the original writing), with an average of about 30 functions each. There are about 2,500 functions in mathematical operations. It doesn't seem to be enough, the PECL warehouse also offers more than 100 extensions, and more on the Internet. "What else is there in addition to the functions in the extension?" "I have heard your doubts. "What's inside the extension?" What is the ' core ' of PHP? "The core of PHP is made up of two parts. At the bottom is the Zend engine (ZE). Ze parses human-readable scripts into machine-readable symbols and executes them within the process space. Ze also handles memory management, variable scopes, and scheduler calls. The other part is the PHP kernel, which binds the SAPI layer (Server application programming Interface, usually involving the host environment, such as apache,iis,cli,cgi, etc.) and handles communication with it. It also provides a consistent layer of control for the detection of Safe_mode and Open_basedir, just as the flow layer links user-space functions such as fopen (), Fread (), and fwrite () to file and network I/O. Life cycle when a given SAPI is started, such as in the response to/usr/local/apache/bin/apachectl start, PHP starts by initializing its kernel subsystem. At the end of the approach to the startup routine, it loads the code for each extension and calls its module initialization routines (MINIT). This allows each extension to initialize internal variables, allocate resources, register resource handlers, and register its own functions with ze so that the script calls this function ze know what code to execute. Next, PHPWait for the SAPI layer to request the page to be processed. For SAPI such as CGI or CLI, this will happen immediately and only once. For Apache, IIS, or other mature Web server SAPI, each time a remote user requests a page, it is repeated many times and may be concurrent. Regardless of how the request was generated, PHP begins with the runtime environment that requires Ze to build the script, and then calls each extended request initialization (Rinit) function. Rinit gives the extension the opportunity to set specific environment variables, allocate resources on request, or perform other tasks, such as auditing. There is a typical example of a Rinit action in the session extension, and if the Session.auto_start option is enabled, Rinit will automatically trigger the Session_Start () function of the user space and the pre-assembled $_session variable. Once the request is initialized, Ze begins to take control and translates the PHP script into symbols, which eventually form the opcode and run gradually. If any of the opcode needs to call the extended function, ze will bind the parameter to the function and temporarily hand over the control until the function is run. After the script is run, PHP calls each extended request-close (Rshutdown) function to perform the final cleanup work (such as saving the session variable to disk). Next, Ze performs the cleanup process (garbage collection)-effectively executing unset () for each variable used during the previous request. Once completed, PHP continues to wait for other document requests from SAPI or to turn off the signal. For SAPI such as CGI and CLI, there is no "next request", so SAPI immediately begins to shut down. During shutdown, PHP iterates through each extension again, invokes its module shutdown (mshutdown) function, and eventually shuts down its own kernel subsystem. This process may sound daunting at first, but once you dive into a functioning extension, you will gradually begin to understand it. Memory allocation in order to avoid poorly written extensions that lose memory, Ze uses additional flags to perform its own internal memory manager to identify persistence. Memory that is durably allocated means more durable than a single request. In contrast, for non-durable allocations during a request, regardless of whether the release (memory) function is invoked, it is freed at the end of the request. For example, the variables for user space are assigned non-persistent because they are useless after the request is finished. In theory, however, extensions can rely on ze to automatically release non-persistent memory at the end of a page request, but this is not recommended. Because the allocated memory will remain in an inactive state for a long time, resources associated with it may not be properly closed, and eating without wiping the mouth is a bad habit. You'll find in a moment that it's easy to actually make sure that all the allocated data is properly cleaned up. Let's simply compare traditional memory allocation functions (which should only be used in external libraries) and php/ze persistent and non-persistent memory non-matching functions. Traditional, non-durable, durablemalloc (count) calloc (count, num) emalloc (count) ecalloc (count, num) Pemalloc (count, 1) *pecalloc (count, num, 1) strdup ( STR) strndup (str, len) estrdup (str) estrndup (str, len) pestrdup (str, 1) pemalloc () & memcpy () free (PTR) efree (PTR) Pefree (PTR, 1) realloc (PTR, newsize) Erealloc (PTR, newsize) Perealloc (PTR, newsize, 1) malloc (count * num + extr) * * Safe_ema Lloc (count, num, extr) safe_pemalloc (count, num, extr) * The Pemalloc () family contains a ' persistent ' flag to allow them to implement the function of the corresponding non-persistent function. For example: Emalloc (1234) is the same as Pemalloc (1234, 0). * * Safe_emalloc () and (PHP 5) Safe_pemalloc () Perform additional detection to prevent integer overflow.
Build the build environment now that you know some of the internal running theories of PHP and the Zend engine, I bet you want to go deeper and start building something. Before you do that, you need to collect some of the necessary build tools and set up an environment that is appropriate for your purposes. First, you need the PHP itself and the set of build tools that it needs. If you are unfamiliar with building PHP from source code, I suggest you look at Http://www.php.net/install.unix. (Developing PHP extensions for Windows will be mentioned in a later article). However, there are some adventures in using PHP's binary bundles, which tend to ignore. Two important options for/configure, which are very handy in the development process. The first of the--enable-debug. This option compiles the additional symbolic information into the PHP execution file so that if a segment error occurs, you can get a kernel dump file from it, use GDB to trace and discover where and why a segment error occurred. Another option depends on your PHP version. in php 4.3, this option is named--enable-experimental-zts and is--enable-maintainer-zts in PHP 5 and later versions. This option allows PHP to assume that it executes in a multithreaded environment and allows you to catch common program errors, but they are harmless in non-multithreaded environments, making your extensions unsafe for multithreaded environments. Once you have compiled PHP with these additional options and installed it on your development server (or workstation), you can add your first extension to it. Hello World What program design introduction can completely ignore the required Hello World program? In this example, you export the extension to a simple function that returns a string containing "Hello world". In PHP, you might do this: Now you will be transferring it to the PHP extension. First, we create a directory named Hello in the directory ext/of your PHP source tree, and ChDir enters the directory. In fact, this directory can be placed anywhere in or out of the PHP source tree, but I would like you to put it here, as an example of an unrelated concept that appears in a later article. You need to create 3 files here: A source file containing the Hello_world function, a reference header file, PHP to load your extension, and phpize to prepare the configuration file for compiling your extension. Config.m4php_arg_enable (Hello, whether to enable Hello World support,[--enable-hello enable Hello World support]) if test "$PHP _hello" = "yes"; Then Ac_define (Have_hello, 1, [Whether has HELLO World]) php_new_extension (Hello, hello.c, $ext _shared) fi Php_hello. H#ifndef php_hello_h#define php_hello_h 1#define php_hello_world_version "1.0" #define Php_hello_world_extname "HELLO" Php_function (Hello_world); extern zend_module_entry hello_module_entry; #define PHPEXT_HELLO_PTR &hello_module_ Entry#endif hello.c#ifdef have_config_h#include "Config.h" #endif # include "Php.h" #include "php_hello.h" static Function_entry hello_functions[] = {Php_fe (Hello_world, null) {null, NULL, Null}};zend_module_entry Hello_module_entry = {#if zend_module_api_no >= 20010901standard_module_header, #endiFphp_hello_world_extname,hello_functions,null,null,null,null,null, #if zend_module_api_no >= 20010901PHP_HELLO_ World_version, #endifSTANDARD_MODULE_PROPERTIES}; #ifdef compile_dl_hellozend_get_module (hello) #endifPHP_FUNCTION (Hello_world) {return_string ("Hello World", 1);} In the example extension above, the code you see is mostly binders, as a protocol language that introduces extensions to PHP and in which sessions are established for communication. Only the last four lines are what you think of as the "Code of Practice", which is responsible for the level of interaction with the scripting of user space. The code looks really much like the PHP code you saw before, and you know it: declaring a function named Hello_world let the function return a string: "Hello World" .... Well.... 1? What happened to that 1 thing? Recall that ze contains a complex memory management layer that ensures that allocated resources are freed when the script exits. However, in the field of memory management, it is absolutely forbidden to release the same piece of memory two times (big no-no). This approach, called two release (double freeing), is a common factor that causes a segment error because it causes the caller to attempt to access memory that is no longer owned. Similarly, you should not allow Ze to release a static string buffer (such as "Hello world" in our example extension) because it exists in the program space and not as a block of data owned by any process. Return_string () can assume that any string passed into it needs to be copied so that it can be safely freed later, but since internal functions are not uncommon to dynamically allocate memory, padding, and return to a string, the second parameter return_string () Allows us to specify whether copies of strings need to be copied. To further illustrate this concept, the following code fragment is equivalent to the corresponding version above: Php_function (hello_world) {char *str;str = estrdup ("Hello World"); Return_string (str, 0);} In this version, you manually allocate memory for the string "Hello world" that will eventually be passed back to the calling script, and then put this fast memory "given" to return_string (), indicated by the second parameter 0It does not need to make its own copy and can have ours. Building your extension The final step in this exercise is to build your extension into a dynamically loaded module. If you have copied the above code correctly, you only need to run 3 commands in ext/hello/: $ phpize$./configure--enable-hello$ make each command run after it can be in the directory ext/hello/modules/ You see the file hello.so. Now, you can copy it to your extension directory like any other extension (default is/usr/local/lib/php/extensions/, check your php.ini to confirm), put extension= hello.so Add your php.ini to make PHP load it when it starts. For CGI/CLI, the next time PHP runs, the Web server needs to be restarted for Web server SAPI, such as Apache. We now try from the command line: $ Php-r ' echo hello_world (); If everything is OK, you will see this script output Hello World, because the function Hello_world () in your loaded extension returns the string, and the echo command outputs the content passed to it (in this case the result of the function). Other scalars can be returned in the same way, integer values with Return_long (), floating-point values with return_double (), True/false values with Return_bool (), Return_null ()? You guessed it, it was null. We look at their respective applications in the instance, by adding a few lines of Php_fe () to the FUNCTION_ENTRY structure in the file hello.c, and adding some php_function () at the end of the file. Static Function_entry hello_functions[] = {Php_fe (hello_world, NULL) Php_fe (Hello_long, NULL) Php_fe (hello_double, NULL ) Php_fe (Hello_bool, NULL) Php_fe (hello_null, null) {NULL, NULL, NULL}}; Php_function (Hello_long) {Return_long (42);} Php_function (hello_double) {return_double (3.1415926535);} Php_function (hello_bool) {Return_booL (1);} Php_function (hello_null) {return_null (); You also need to add a prototype declaration of these functions next to the prototype declaration of the function Hello_world () in the header file Php_hello.h, so that the build process is correct: php_ FUNCTION (Hello_world); Php_function (Hello_long); Php_function (hello_double); Php_function (Hello_bool); Php_function (Hello_null); Since you did not change the file config.m4, this time skipping phpize and./configure steps to jump directly to make is technically safe. However, at this point I want you to finish all the build steps again to make sure that it is well built. In addition, you should call make clean all instead of simply making in the last step to ensure that all source files are rebuilt. Again, so far, these (steps) are not required according to the type of change you have made, but security is better than confusion. Once the module is built, copy it to your extension directory again, replacing the old version. At this point you can call the PHP interpreter again and simply pass in the script to test the function you just added. In fact, why not do it now? I'll be right here waiting ... It's done? Good. If you use Var_dump () instead of ECHO to see the output of each function, you may notice that Hello_bool () returns True. That is the result of the value 1 in Return_bool (). As in the PHP script, the integer value 0 equals false, and the other integer equals True. Just as a convention, extension authors usually use 1 to encourage you to do the same, but don't feel constrained by it. For additional readability purposes, macros Return_true and Return_false are also available; another hello_bool (), this time using Return_true:php_function (hello_bool) {return_true;} Note that there is no parentheses here. In that case, unlike other macro return_* (), return_true and Return_false have different styles (is aberrations), so be sure not to be misled by it (to get caught by this one). You probably noticed that in each of the examples above, we didn't pass in 0 or 1 to indicate whether or not to copy. This is because there is no need to allocate or free additional memory for such simple small scalars (except for the variable container itself-we will examine it in more depth in the second part.) ) There are other threeType of return: resources (just like mysql_connect (), Fsockopen () and Ftp_connect () return the names of the values, but not limited to this), arrays (also known as hashes) and objects (returned by the keyword new). We will see them in the second part when we are going into the variables in depth. The initial setup (INI) Zend Engine provides two ways to manage INI values. Now let's look at the simpler ones and then explore the more sophisticated but more complex ways of working with global data. Suppose you want to define a value for your extension in php.ini, hello.greeting, which holds the greeting string that will be used in the Hello_world () function. You need to add some code to HELLO.C and php_hello.h, while making some critical changes to the hello_module_entry structure. The following prototype is added to the prototype declaration near the user space function in file php_hello.h: php_minit_function (hello); Php_mshutdown_function (hello); Php_function (Hello_world); Php_function (Hello_long); Php_function (hello_double); Php_function (Hello_bool); Php_function (Hello_null); Now go to file hello.c, remove the current version of Hello_module_entry, replace it with the following list: Zend_module_entry hello_module_entry = {#if zend_module_api_no >= 20010901standard_module_header, #endifPHP_HELLO_WORLD_EXTNAME, Hello_functions,php_minit (HELLO), Php_ Mshutdown (hello), null,null,null, #if zend_module_api_no >= 20010901php_hello_world_version, #endifSTANDARD_ Module_properties}; Php_ini_begin () php_ini_entry ("hello.greeting", "Hello World", Php_ini_all, NULL) php_ini_end () php_minit_function (HEllo) {register_ini_entries (); return SUCCESS;} Php_mshutdown_function (Hello) {unregister_ini_entries (); return SUCCESS; Now you just need to add a # next to those # include on the top of the file hello.c Include, which will get the correct support for the INI header file: #ifdef have_config_h#include "Config.h" #endif # include "Php.h" #include "php_ini.h" # Include "Php_hello.h" Finally, you can modify the function Hello_world Let it use the value of INI: Php_function (hello_world) {return_string (Ini_str (" Hello.greeting "), 1);} Note that you are going to copy the value returned from INI_STR (). This is because, before entering the PHP variable stack (as far as the PHP variable stack is concerned), it is a static string. In fact, if you try to modify the returned string, the PHP execution environment will become unstable and even crash. The first change in this section introduces two functions that you are very familiar with: Minit and Mshutdown. As mentioned earlier, these methods are called during SAPI initial start and final shutdown. They are not called between the request and the request. In this example, they are used to register the entries defined in your extension with php.ini. In the tutorial later in this series, you will also see how to register resources, objects, and stream processors using the Minit and Mshutdown functions. The function Hello_world () uses INI_STR () to obtain the current string value of the hello.greeting entry. Other similar functions are used to obtain other types of values, long integers, double-precision floating-point types, and Booleans, as shown in the table below, as well as additional orig versions that provide INI (the original) settings in the php.ini file (in the. htaccess or Ini_set () Before the instruction Change) (original: Provides the value of the referenced INI setting as it is set in php.ini-). Current value original value type INI_STR (name) ini_orig_str (name) char * (NULL terminated) Ini_int (name) ini_orig_int (name) signed Longini_flt (name) Ini_orig_flt (name) signed Doubleini_bool (name) The first argument to Ini_orig_bool (name) zend_bool incoming php_ini_entry () contains a string of names used in the php.ini file. To avoid namespace collisions, you should use the same convention as the same function, that is, prefix the name of your extension with all values, as you did with hello.greeting. Just as a convention, a period is used to separate the name of the extension and the more descriptive initial setting name. The second parameter is the initial value (the default value?). , and, regardless of whether it is a numeric value, use a string of type char*. This is mainly based on the fact that the original value in the. ini file is text-and everything else is stored as a text file. The Ini_int (), Ini_flt (), or ini_bool () that you used in the later script will convert the type. The third value passed in is the access pattern modifier. This is the single-bit mask field, which determines when and where the INI value is modifiable. For some of these, such as register_globals, it simply does not allow Ini_set () to change the value in the script, because this setting is meaningful only during the request startup period (before the script can run). Other, such as Allow_url_fopen, is the management (the staff can do) setting, you do not want to share the host environment users to modify it, whether through ini_set () or. htaccess instructions. The typical value of this parameter may be php_ini_all, indicating that the value can be modified anywhere. And then there's php_ini_system|. Php_ini_perdir, indicates that the setting can be modified in the php.ini file, or modified by the Apache directive in the. htaccess file, but cannot be modified with Ini_set (). Alternatively, Php_ini_system can be used to indicate that the value is only modified in the php.ini file, not anywhere else. We now omit the fourth argument, just to mention that it allows a method callback to be triggered when the initial setting changes-for example, with Ini_set (). This allows the extension to perform more precise control when the setting is changed, or to trigger a related behavior based on the new setting. Global numeric extensions often require a value to be traced from beginning to end in a particular request and to separate it from other requests that may occur concurrently. In a non-multithreaded sapi, it's simple: just declare a in the source fileglobal variable and access it when needed. The problem is that because PHP is designed to run in a multithreaded Web server (such as Apache 2 and IIS), it needs to keep the global values used by each thread separate. By using TSRM (thread safe Resource Management, Thread-safe resource manager) abstraction Layer-sometimes referred to as ZTS (Zend thread safety,zend threading security), PHP greatly simplifies it. In fact, at this point you've used some tsrm, just not aware of it. (Don't look too hard; With this series, you'll see it everywhere.) As with any global scope, the first step in creating a thread-safe scope is to declare it. Given the goal of this example, you will declare a long global numeric value of 0. Each time Hello_long () is called, the value is increased by 1 and returned. Add the following code snippet after the # define PHP_HELLO_H statement in the php_hello.h file: #ifdef zts#include "TSRM.h" #endifZEND_BEGIN_MODULE_GLOBALS (Hello) Long counter; Zend_end_module_globals (Hello) #ifdef zts#define hello_g (v) tsrmg (hello_globals_id, zend_hello_globals *, v) #else # Define Hello_g (v) (HELLO_GLOBALS.V) #endif will also use the Rinit method this time, so you need to declare its prototype in the header file: Php_minit_function (HELLO); Php_mshutdown_function (hello); Php_rinit_function (hello); Now let's go back to the file hello.c and add the following code immediately after the block containing the code: #ifdef have_config_h#include "Config.h" #endif # include "Php.h" #include "php_ Ini.h "#include" php_hello.h "zend_declare_module_globals (Hello) change hello_module_entry, join Php_rinit (hello): zend_ Module_entry hello_module_entry = {#if zend_module_api_no>= 20010901standard_module_header, #endifPHP_HELLO_WORLD_EXTNAME, Hello_functions,php_minit (HELLO), Php_ Mshutdown (Hello), php_rinit (hello), null,null, #if zend_module_api_no >= 20010901php_hello_world_version,# Endifstandard_module_properties}; and modify your Minit function with two additional functions that perform initialization at request startup: static void Php_hello_init_globals (Zend_hello_globals *hello_globals) {}php_ Rinit_function (Hello) {hello_g (counter) = 0;return SUCCESS;} Php_minit_function (Hello) {zend_init_module_globals (hello, php_hello_init_globals, NULL); Register_ini_entries (); return SUCCESS;} Finally, you can modify the Hello_long () function to use this value: Php_function (hello_long) {hello_g (counter) + +; Return_long (Hello_g (counter));} In the code you added to Php_hello.h, you used two macros-zend_begin_module_globals () and zend_end_module_globals ()-Used to create a named Zend_hello_ The structure of the Globals, which contains a long type of variable. Then conditionally define HELLO_G () to take a value from the thread pool, or get it from the global scope-if you are compiling a non-multithreaded environment. In hello.c, you use the Zend_declare_module_globals () macro to sample the zend_hello_globals structure, or the real global (if the build is non-thread-safe), or a member of the resource pool for this thread. As an extension author, we don't need to worry about their differences, because the Zend engine is doing this for us. Finally, you use Zend_init_mod in the Minit.Ule_globals () allocates a thread-safe resource id-Now you don't have to think about what it is. You may have noticed that php_hello_init_globals () actually did nothing, but had to declare more than one rinit to initialize the variable counter to 0. Why? The key is when these two functions are called. Php_hello_init_globals () is called only when a new process or thread is started, but each process can handle multiple requests, so using this function to initialize the variable counter to 0 will only run on the first page request. Subsequent page requests made to the same process will still get the value of the counter variable stored here, so it will not count from 0 onwards. To initialize the counter variable to 0 for each page request, we implement the Rinit function, as seen before, which is called before each page request. At this point we include the php_hello_init_globals () function because you will use it later, and passing NULL in Zend_init_module_globals () for this initialization function will result in a segment error on a non-multithreaded platform. Initial setup (INI) as a global value recall that a PHP.ini value declared with Php_ini_entry () is parsed as a string and converted to another format using Ini_int (), Ini_flt (), and Ini_bool (). For some settings, doing so makes it possible to do a lot of unnecessary repetitive work while reading these values during the execution of the script. Fortunately, you can have ze store the INI value as a specific data type and only perform a type conversion when its value is changed. We try it by declaring another INI value, this time being a Boolean value that indicates whether the variable counter is incremented or decremented. Let's start by changing the module_globals block in php_hello.h to the following code: zend_begin_module_globals (Hello) long counter;zend_bool direction; Zend_end_module_globals (Hello) Next, modify the Php_ini_begin () block, declaring the INI value, like this: Php_ini_begin () php_ini_entry ("Hello.greeting", "Hello World", Php_ini_all, NULL) std_php_ini_entry ("Hello.direction", "1", Php_ini_all, Onupdatebool, direction, Zend_hello_globals, Hello_globals) php_ini_end () Now initializes the settings in the Init_globals method with the following code: static void Php_hello_init_globals ( Zend_hello_globals *hello_globals) {hello_globals->direction = 1;} and finally, apply this initial setting in Hello_long () to determine whether to increment or decrement: php_ FUNCTION (Hello_long) {if (Hello_g (direction)) {Hello_g (counter) + +;} else {Hello_g (counter)--;} Return_long (Hello_g (counter));} That's all. The Onupdatebool method specified in the Ini_entry section automatically converts the values provided by Ini_set () in the php.ini,. htaccess, or script to the appropriate True/false values so that you can access them directly in the script. The last three parameters of Std_php_ini_entry tell PHP which global variable to change, what is the structure of our extended global (scope), and what is the name of the global scope that holds the variables. Check (code) integrity to date, our three files should resemble the following list. (for readability, some items have been moved and re-organized.) ) config.m4php_arg_enable (Hello, whether to enable Hello World support,[--enable-hello enable Hello World support]) if test "$PHP _hello" = "yes"; Then Ac_define (Have_hello, 1, [Whether has HELLO World]) php_new_extension (Hello, hello.c, $ext _shared) fi Php_hello. H#ifndef php_hello_h#define php_hello_h 1#ifdef zts#include "TSRM.h" #endifZEND_BEGIN_MODULE_GLOBALS (HELLO) long Counter;zend_bool DirectioN Zend_end_module_globals (Hello) #ifdef zts#define hello_g (v) tsrmg (hello_globals_id, zend_hello_globals *, v) #else # Define Hello_g (v) (HELLO_GLOBALS.V) #endif # define Php_hello_world_version "1.0" #define PHP_HELLO_WORLD_EXTNAME "HELLO "Php_minit_function (hello); Php_mshutdown_function (hello); Php_rinit_function (hello); Php_function (Hello_world); Php_function (Hello_long); Php_function (hello_double); Php_function (Hello_bool); Php_function (hello_null); extern zend_module_entry hello_module_entry; #define PHPEXT_HELLO_PTR &hello_module_ Entry#endif hello.c#ifdef have_config_h#include "Config.h" #endif # include "Php.h" #include "php_ini.h" #include "php_ Hello.h "zend_declare_module_globals (hello) static function_entry hello_functions[] = {Php_fe (Hello_world, NULL) php_ FE (Hello_long, NULL) Php_fe (hello_double, NULL) Php_fe (Hello_bool, NULL) Php_fe (hello_null, null) {NULL, NULL, NULL}}; Zend_module_entry hello_module_entry = {#if zend_module_api_no >= 20010901standard_module_header, #endifPHP_HELLO_ World_extname, Hello_functions,php_minit (hello), Php_mshutdown (hello), php_rinit (hello), null,null, #if zend_module_api_no >= 20010901php_hello_world_version, #endifSTANDARD_MODULE_PROPERTIES}; #ifdef Compile_dl_hellozend_get_module (HELLO) #endifPHP_INI_BEGIN () php_ini_entry ("hello.greeting", "Hello World", Php_ini_all, NULL) std_php_ini_entry (" Hello.direction "," 1 ", Php_ini_all, Onupdatebool, direction, zend_hello_globals, Hello_globals) php_ini_end () static void Php_hello_init_globals (Zend_hello_globals *hello_globals) {hello_globals->direction = 1;} Php_rinit_function (Hello) {hello_g (counter) = 0;return SUCCESS;} Php_minit_function (Hello) {zend_init_module_globals (hello, php_hello_init_globals, NULL); Register_ini_entries (); return SUCCESS;} Php_mshutdown_function (Hello) {unregister_ini_entries (); return SUCCESS;} Php_function (Hello_world) {return_string ("Hello World", 1);} Php_function (Hello_long) {if (Hello_g (direction)) {Hello_g (counter) + +;} else {Hello_g (counter)--;} Return_long (Hello_g (counter));} Php_function (Hello_double) {return_double (3.1415926535);} Php_function (Hello_bool) {return_bool (1);} Php_function (hello_null) {return_null ();}
What's the next step? This tutorial explores the structure of a simple PHP extension, including exporting functions, return values, declaring initial settings (INI), and tracking their internal state during (client) requests. In the next section, we'll explore the internal structure of PHP variables and how to store, track, and maintain them in a scripting environment. When the function is called, we will use Zend_parse_parameters to receive parameters from the program and explore how to return more complex results, including the types of arrays, objects, and resources mentioned in this tutorial.

http://www.bkjia.com/PHPjc/735137.html www.bkjia.com true http://www.bkjia.com/PHPjc/735137.html techarticle Original: Http://devzone.zend.com/public/view/tag/ExtensionPart i:introduction to PHP and Zend Write extensions i-php and Zend Start/HTTP// Devzone.zend.com/article/1021-extension-writing-...

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.