


Extension and embedding of php--php internal variables_PHP tutorial
I previously introduced the internal life cycle of PHP and the thread safety mechanism of the Zend engine. This article here mainly introduces how the internal variables of PHP are implemented.
After understanding these implementation methods, it feels very helpful for writing PHP, especially for PHP extension development.
PHP is a relatively loosely typed language. Compared with C, you don’t need to give the type before using the variable, you can just use it directly. In order to achieve this, PHP has to do some work on the definition of data types.
Data type:
The most basic type is called zval or Zend Value, defined in the Zend/zend.h header file. typedef struct _zval_struct {zvalue_value value;
zend_uint refcount;
zend_uchar type;
zend_uchar is_ref;
} zval; Among them, zvalue_value is defined as follows: typedef union _zvalue_value {
long lval;
double dval;
struct {
char *val;
int len;
} str;
HashTable *ht;
zend_object_value obj;
} zvalue_value; This is a union. There are two possibilities when using union. One is when all variables share a memory space, and the other is when one of the types needs to be selected from n.
Zend defines 8 basic data types. These eight are basically seen in other languages, so only the more special types are explained: IS_NULL: non-valueIS_BOOL: IS_LONGIS_DOUBLEIS_STRING: The allocated space needs to be length + 1IS_ARRAY: The array of php is actually a hashtable, including label and dataIS_OBJECT: On the basis of the array, methods, access modifiers, domain constants and special are added Event handler IS_RESOURCE: For example, file handles or mysql handles are stored in the type of zval and have separate correspondences with zvalue_value Note that there is a comparison of the two type judgment functions below:
void describe_zval(zval *foo) { if (foo->type == IS_NULL) { php_printf("The variable is NULL"); } else { php_printf("The variable is of type %d", foo->type); } }
void describe_zval(zval *foo) { if (Z_TYPE_P(foo) == IS_NULL) { php_printf("The variable is NULL"); } else { php_printf("The variable is of type %d", Z_TYPE_P(foo)); } }
The first piece of code is written in C, and the second piece of code is written in PHP style. Note that the Zend header file provides many macros for zval processing. It is best to use them. Here, Z_TYPE_P(foo) is used. There are also Z_TYPE() and Z_TYPE_PP() corresponding to zval and zval** respectively php_printf() is based on printf and has made some optimizations for SAPI and PHP output mechanisms.
Data value
The values of different types of zval can be obtained through some macros: BVAL(): BooleanLVAL(): longDVAL(): double This function uses Z_TYPE to perform type judgment for three different zval types. Then use the corresponding value extraction macro to obtain the value.void display_values(zval boolzv, zval *longpzv, zval **doubleppzv) { if (Z_TYPE(boolzv) == IS_BOOL) { php_printf("The value of the boolean is: %s\n", Z_BVAL(boolzv) ? "true" : "false"); } if (Z_TYPE_P(longpzv) == IS_LONG) { php_printf("The value of the long is: %ld\n", Z_LVAL_P(longpzv)); } if (Z_TYPE_PP(doubleppzv) == IS_DOUBLE) { php_printf("The value of the double is: %f\n", Z_DVAL_PP(doubleppzv)); } }
The processing of string is slightly more special: two macros Z_STRVA and Z_STRLEN are needed to read the value and length respectively. This can also be seen from the definition of the string type, which is Composed of characters and length.
void display_string(zval *zstr) { if (Z_TYPE_P(zstr) != IS_STRING) { php_printf("The wrong datatype was passed!\n"); return; } PHPWRITE(Z_STRVAL_P(zstr), Z_STRLEN_P(zstr)); }
Access to the array uses the ARRVAL series: Z_ARRVAL(zv), Z_ARRVAL_P(pzv), Z_ARRVAL_PP(ppzv). In some versions of PHP source code, HASH_OF() is equivalent to Z_ARRVAL_P, but this macro has gradually become less used.
For Object: OBJ_HANDLE returns the object handle identifier OBJ_HT handle table OBJCE class definition OBJPROP attribute hash table OBJ_HANDLER operates specific processing methods in OBJ_HT For resources, just use the macro RESVAL directly.
Data creation:
想要创造一个变量并分配空间的malloc(sizeof(zval))在php这里并不可行。应该使用MAKE_STD_ZVAL(pzv), 它对空间的分配进行了优化,并且会自动的初始化refCount(表示这个变量被引用的次数)和is_ref(是否是强制引用)这两个性质。注意它的输入是一个指针.ALLOC_INIT_ZVAL()也可以进行初始化,不同之处在于把zval*的值设为了NULL.
在设置不同类型的值的时候有很多形式,左边是比较简略的形式,右侧则是展开的形式: ZVAL_NULL(pvz); Z_TYPE_P(pzv) = IS_NULL;
ZVAL_BOOL(pzv, b); Z_TYPE_P(pzv) = IS_BOOL;
Z_BVAL_P(pzv) = b ? 1 : 0;
ZVAL_TRUE(pzv); ZVAL_BOOL(pzv, 1);
ZVAL_FALSE(pzv); ZVAL_BOOL(pzv, 0);
ZVAL_LONG(pzv, l); Z_TYPE_P(pzv) = IS_LONG;
Z_LVAL_P(pzv) = l;
ZVAL_DOUBLE(pzv, d); Z_TYPE_P(pzv) = IS_DOUBLE;
Z_DVAL_P(pzv) = d;
对于字符串的处理要特殊一些,提供了一个单独的参数dup. 这个参数决定了是否创建一个字符串的副本.举个例子 zval * pzva; ZVAL_STRING(pzval,"hello world",1); 由于“hello_world”是一个常量字符串,直接对它进行操作显然不合适,所以把dup设为1的话,会自动的给它创建一个副本,然后再赋给pzval. 这使得整个过程更加简洁。
ZVAL_STRINGL(pzv,str,len,dup); Z_TYPE_P(pzv) = IS_STRING;
Z_STRLEN_P(pzv) = len;
if (dup) {
Z_STRVAL_P(pzv) =
estrndup(str, len + 1);
} else {
Z_STRVAL_P(pzv) = str;
}
ZVAL_STRING(pzv, str, dup); ZVAL _STRINGL(pzv, str,
strlen(str), dup); 注意dup如果设为1的话就是申请新的空间并且拷贝内容,而不是一个shaddow copy。 ZVAL_RESOURCE(pzv, res); Z_TYPE_P(pzv) = IS_RESOURCE;
Z_RESVAL_P(pzv) = res;
数据的存储
数据的存储都在符号表中。 symbol table,每当创建一个新的变量的时候,Zend都保存这个值到这个内部的数组中去。 符号表在RINIT之前创建,在RSHUTDOWN之后销毁。当用户空间的函数或对象方法被调用的时候,会创建一个新的符号表,生命与函数执行时间相同。 在Zend/zend_gblobals.h中定义了两个元素:
struct _zend_executor_globals { ... HashTable symbol_table; HashTable *active_symbol_table; ... };
通过EG(symbol_table) 的方式可以访问符号表。感觉跟$GLOBALS似的。 注意到EG(symbol_table)这个宏返回的不是指针,必须加上&。 下面的这个对比非常的有趣: In PHP:
<?php $foo = 'bar'; ?>
In C:
{ zval *fooval; MAKE_STD_ZVAL(fooval); //首先分配空间,设置变量 ZVAL_STRING(fooval, "bar", 1); //然后赋值,创建一个copy,你不能直接操作常字符串 ZEND_SET_SYMBOL(EG(active_symbol_table), "foo", fooval); // 在符号表中注册,foo是一个label }
数据的获取: 在获取数据的时候,比较多的是使用zend_hash_find()函数:
{ zval **fooval; if (zend_hash_find(EG(active_symbol_table), "foo", sizeof("foo"), (void**)&fooval) == SUCCESS) { php_printf("Got the value of $foo!"); } else { php_printf("$foo is not defined."); } }
数据转换: 仅仅是说一下有这个功能,比如convert_to_string(zval *value)可以把zval转换为字符串。
以上就是php内部变量的一些介绍,为了能够区分不同的类型、设置获取变量值以及在符号表中增加和查找变量,这些知识必不可少。

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



The SNMP extension for PHP is an extension that enables PHP to communicate with network devices through the SNMP protocol. Using this extension, you can easily obtain and modify the configuration information of network devices, such as CPU, memory, network interface and other information of routers, switches, etc. You can also perform control operations such as switching device ports. This article will introduce the basic knowledge of the SNMP protocol, how to install the SNMP extension of PHP, and how to use the SNMP extension in PHP to monitor and control network devices. 1. SN

From start to finish: How to use php extension cURL for HTTP requests Introduction: In web development, it is often necessary to communicate with third-party APIs or other remote servers. Using cURL to make HTTP requests is a common and powerful way. This article will introduce how to use PHP to extend cURL to perform HTTP requests, and provide some practical code examples. 1. Preparation First, make sure that php has the cURL extension installed. You can execute php-m|grepcurl on the command line to check

The combination of PHP and HTML is a common technology in web development. PHP can embed dynamic content in HTML files and implement auxiliary functions, which greatly improves the interactivity and customizability of the website. This article will introduce three techniques for embedding code and provide specific code examples for reference. 1. Use PHP tags to embed code. The most common way is to use PHP tags () to embed PHP code into HTML files to display dynamic content. For example, you can use PHP

To extend PHP function functionality, you can use extensions and third-party modules. Extensions provide additional functions and classes that can be installed and enabled through the pecl package manager. Third-party modules provide specific functionality and can be installed through the Composer package manager. Practical examples include using extensions to parse complex JSON data and using modules to validate data.

1.UncaughtError:Calltoundefinedfunctionmb_strlen(); When the above error occurs, it means that we have not installed the mbstring extension; 2. Enter the PHP installation directory cd/temp001/php-7.1.0/ext/mbstring 3. Start phpize(/usr/local/bin /phpize or /usr/local/php7-abel001/bin/phpize) command to install php extension 4../configure--with-php-config=/usr/local/php7-abel

How to use the Aurora Push extension to implement batch message push function in PHP applications. In the development of mobile applications, message push is a very important function. Jiguang Push is a commonly used message push service that provides rich functions and interfaces. This article will introduce how to use the Aurora Push extension to implement batch message push functionality in PHP applications. Step 1: Register a Jiguang Push account and obtain an API key. First, we need to register on the Jiguang Push official website (https://www.jiguang.cn/push)

PHP is a popular server-side language that can be used to develop web applications and process files. The ZipArchive extension for PHP is a powerful tool for manipulating zip files in PHP. In this article, we’ll cover how to use PHP’s ZipArchive extension to create, read, and modify zip files. 1. Install the ZipArchive extension. Before using the ZipArchive extension, you need to ensure that the extension has been installed. The installation method is as follows: 1. Install

The POSIX extensions for PHP are a set of functions and constants that allow PHP to interact with POSIX-compliant operating systems. POSIX (PortableOperatingSystemInterface) is a set of operating system interface standards designed to allow software developers to write applications that can run on various UNIX or UNIX-like operating systems. This article will introduce how to use POSIX extensions for PHP, including installation and use. 1. Install the POSIX extension of PHP in
