


PHP extension and embedding--Parameters of PHP extension_PHP tutorial
In previous articles, functions are relatively simple in terms of the parameters they receive and the types they return, but what is often encountered in practice is more complex. This article mainly talks about how to receive parameters from user space in PHP extension development, and check the type, number and other information of these parameters accordingly.
1. Use zend_parse_parameters() for automatic type conversion
In PHP extensions, the easiest way to get input parameters is to use the zend_parse_parameters() function.
The first argument to a call to this function is always: ZEND_NUM_ARGS() TSRMLS_CC. This argument returns the number of input arguments as an int.The second parameter is the format parameter, which is composed of string types, corresponding to different types supported by Zend Engine.
The following figure shows the possible types of the format parameter:

The following parameters depend on the type requested previously. For relatively simple types, this parameter is usually a referenced primitive, as shown in the following example:
PHP_FUNCTION(sample_getlong) { long foo; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &foo) == FAILURE) { RETURN_NULL(); } php_printf("The integer value of the parameter you " "passed is: %ld\n", foo); RETURN_TRUE; }Here is l, which is a long type, so accordingly a long foo parameter is declared in advance, and then the value is passed in by reference. The following gives a more detailed correspondence between parameters and types in the C language: b ------ zend_bool l ------- long d ------- double s ------- char* , int r ------- zval* a ------ zval* o ------ zval* O ----- zval*, zend_class_entry* z ------ zval* Z ----- zval**
Note that for complex types, simple zval* types are used. This is the same as the reason why there is no RETURN_* when returning a complex type. What ZPP does is ensure that the received zval* is of the correct type. If necessary, it will also perform implicit conversions, such as converting arrays to stdClass objects.
For the s type, it is quite special, one char* one int. This is mainly because of the special structure of strings in php:
function sample_hello_world($name) { echo "Hello $name!\n"; }In C language, the zend_parse_parameters function is used:
PHP_FUNCTION(sample_hello_world) { char *name; int name_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { RETURN_NULL(); } php_printf("Hello "); PHPWRITE(name, name_len); php_printf("!\n"); }
If there are multiple parameters, zend_parse_parameters will extract these parameters from left to right:
function sample_hello_world($name, $greeting) { echo "Hello $greeting $name!\n"; } sample_hello_world('John Smith', 'Mr.');
Or:
PHP_FUNCTION(sample_hello_world) { char *name; int name_len; char *greeting; int greeting_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &greeting, &greeting_len) == FAILURE) { RETURN_NULL(); } php_printf("Hello "); PHPWRITE(greeting, greeting_len); php_printf(" "); PHPWRITE(name, name_len); php_printf("!\n"); }
In addition to the type identifier, there are three metacharacters that modify how parameters are processed: | : If you see it, it means that the previous parameters are required and the following parameters are optional! : If a null variable in the PHP language is received, it will be directly converted to NULL in the C language instead of Encapsulated into zval
of type IS_NULL /: If the passed variable shares a zval with other variables and is not a true reference, it must be forcibly separated. The new zval's is_ref__gc = 0, refcount__gc = 1 Optional parameters: Default values can be provided for parameters in php:
function sample_hello_world($name, $greeting='Mr./Ms.') { echo "Hello $greeting $name!\n"; }At this time, when calling, you do not need to provide the second parameter:
sample_hello_world('Ginger Rogers','Ms.'); sample_hello_world('Fred Astaire');
In the C interpretation, there is a similar implementation:
PHP_FUNCTION(sample_hello_world) { char *name; int name_len; char *greeting = "Mr./Mrs."; int greeting_len = sizeof("Mr./Mrs.") - 1;//给定默认值,找出默认的长度 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &name, &name_len, &greeting, &greeting_len) == FAILURE) {//特殊的元字符|立刻就用上了 RETURN_NULL(); } php_printf("Hello "); PHPWRITE(greeting, greeting_len); php_printf(" "); PHPWRITE(name, name_len); php_printf("!\n"); }
Optional parameters generally have no value unless specified, so it is important to provide default parameters. In most cases it is NULL/0
IS_NULL VS NULL:
Each zval type, even the simplest IS_NULL type, occupies a certain amount of memory space, and it also takes time to apply for and release them. Therefore, there is no need to use this type in many cases. The comparison is given in the following two pieces of code:
PHP_FUNCTION(sample_arg_fullnull) { zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &val) == FAILURE) { RETURN_NULL(); } if (Z_TYPE_P(val) == IS_NULL) {//使用zval检查为空的方式 val = php_sample_make_defaultval(TSRMLS_C); } ... PHP_FUNCTION(sample_arg_nullok) { zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!", &val) == FAILURE) { RETURN_NULL(); } if (!val) {// c语言风格的检查为空的方式 val = php_sample_make_defaultval(TSRMLS_C); } ...
Forced Seperation:
When a variable is passed into a function, regardless of whether it is passed by reference or not, the refcount is always at least 2. One is itself and the other is the copy passed into the function. Before making changes to this zval, it is necessary to separate it from a non-referenced collection.
It is very convenient to use /, which will automatically separate any variables referenced by copy-on-write (that is, false references).
This feature is the same as the NULL flag and is only used when needed.
zend_get_parameters():
If you want to be compatible with older versions of PHP or just want to use zval as a carrier to receive parameters, you can consider using the zend_get_parameters() function to receive parameters
Compared with zend_parse_parameters(), it is obtained directly without parsing. Type conversion will not be performed automatically. The carriers of all parameters in the extended implementation are zval.
ZEND_FUNCTION(sample_onearg) {
zval *firstarg; if (zend_get_parameters(ZEND_NUM_ARGS(), 1, &firstarg)== FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Expected at least 1 parameter."); RETURN_NULL(); } /* Do something with firstarg... */ }
At the same time, it will not throw an error when receiving fails, nor can it handle parameters with default values. The last difference from parse is that it will automatically forcefully separate all zvals that comply with copy-on-write. Generate a fresh copy and send it inside the function.
If you don’t need this function, you can use zend_get_parameters_ex() whose parameters are zval**
ZEND_FUNCTION(sample_onearg) { zval **firstarg; if (zend_get_parameters_ex(1, &firstarg) == FAILURE) { WRONG_PARAM_COUNT;抛出一个E_WARNING级别的错误信息,并自动return。 } /*
Variable parameters, handle any number of parameters:
There are also two zend_get_parameters_** functions, which are specially used to solve situations where there are many or the number of parameters cannot be known in advance. The var_dump() function in the PHP language can input any number of parameters.
ZEND_FUNCTION(var_dump) { int i, argc = ZEND_NUM_ARGS(); zval ***args; args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0); if (ZEND_NUM_ARGS() == 0 || zend_get_parameters_array_ex(argc, args) == FAILURE) { efree(args); WRONG_PARAM_COUNT; } for (i=0; i<br> 程序首先获取参数数量,然后通过safe_emalloc函数申请相应大小的内存来存储这些zval**的参数。这里使用zend_get_parameters_array_ex()函数来把传递给函数的参数填充到args中。提醒一下,还存在一个zend_get_parameters_array()函数,唯一不同是它将zval*类型的参数填充到args中,并且需要ZEND_NUM_ARGS()作为参数。<br> </p> <p><br> </p> <p><br> </p> <p><strong>2. Arg info参数和类型的绑定</strong></p> <p>这个arg info结构是ZE2才有的。每一个arg info声明都由一个ZEND_BEGIN_ARG_INFO()或ZEND_BEGIN_ARG_INFO_EX()宏组成,后面跟着0个或多个ZEND_ARG_*INFO(), 然后最后以ZEND_END_ARG_INFO()作为结尾。<br> 假定要重写count()函数:<br> </p> <p><pre class="code">PHP_FUNCTION(sample_count_array) { zval *arr; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) { RETURN_NULL(); } RETURN_LONG(zend_hash_num_elements(Z_ARRVAL_P(arr))); }
zend_parse_parameters()会确保输入到你函数中的参数是一个数组。但是如果你需要用zend_get_parameter()的话,那么就需要自己在函数内部内建类型检查。除非使用类型绑定:
ZEND_BEGIN_ARG_INFO(php_sample_array_arginfo, 0) ZEND_ARG_ARRAY_INFO(0, "arr", 0) ZEND_END_ARG_INFO() 。。。 PHP_FE(sample_count_array, php_sample_array_arginfo) 。。。
通过这种方式,zend engine就会帮你进行类型检查了。同时还给了参数一个名字,从而使得产生的错误信息更加具有可读性。
而对于对象来说,也可以通过arg info进行限定:
ZEND_BEGIN_ARG_INFO(php_sample_class_arginfo, 0) ZEND_ARG_OBJECT_INFO(1, "obj", "stdClass", 0) ZEND_END_ARG_INFO()
这里第一个参数被设为1,表示是引用方式传递,但是对象其实在ZE2中都是引用传递的。不要忘记了array和object的allow_null选项。
如果使用的是php4的话,只能用PHP_TYPE_P()进行检查,或使用convert_to_type()方法进行类型转换。

What’s still popular is the ease of use, flexibility and a strong ecosystem. 1) Ease of use and simple syntax make it the first choice for beginners. 2) Closely integrated with web development, excellent interaction with HTTP requests and database. 3) The huge ecosystem provides a wealth of tools and libraries. 4) Active community and open source nature adapts them to new needs and technology trends.

PHP and Python are both high-level programming languages that are widely used in web development, data processing and automation tasks. 1.PHP is often used to build dynamic websites and content management systems, while Python is often used to build web frameworks and data science. 2.PHP uses echo to output content, Python uses print. 3. Both support object-oriented programming, but the syntax and keywords are different. 4. PHP supports weak type conversion, while Python is more stringent. 5. PHP performance optimization includes using OPcache and asynchronous programming, while Python uses cProfile and asynchronous programming.

PHP is mainly procedural programming, but also supports object-oriented programming (OOP); Python supports a variety of paradigms, including OOP, functional and procedural programming. PHP is suitable for web development, and Python is suitable for a variety of applications such as data analysis and machine learning.

PHP originated in 1994 and was developed by RasmusLerdorf. It was originally used to track website visitors and gradually evolved into a server-side scripting language and was widely used in web development. Python was developed by Guidovan Rossum in the late 1980s and was first released in 1991. It emphasizes code readability and simplicity, and is suitable for scientific computing, data analysis and other fields.

PHP is suitable for web development and rapid prototyping, and Python is suitable for data science and machine learning. 1.PHP is used for dynamic web development, with simple syntax and suitable for rapid development. 2. Python has concise syntax, is suitable for multiple fields, and has a strong library ecosystem.

PHP remains important in the modernization process because it supports a large number of websites and applications and adapts to development needs through frameworks. 1.PHP7 improves performance and introduces new features. 2. Modern frameworks such as Laravel, Symfony and CodeIgniter simplify development and improve code quality. 3. Performance optimization and best practices further improve application efficiency.

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP type prompts to improve code quality and readability. 1) Scalar type tips: Since PHP7.0, basic data types are allowed to be specified in function parameters, such as int, float, etc. 2) Return type prompt: Ensure the consistency of the function return value type. 3) Union type prompt: Since PHP8.0, multiple types are allowed to be specified in function parameters or return values. 4) Nullable type prompt: Allows to include null values and handle functions that may return null values.


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

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

WebStorm Mac version
Useful JavaScript development tools

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Zend Studio 13.0.1
Powerful PHP integrated development environment