search
HomeBackend DevelopmentPHP TutorialWriting parameters for PHP extension functions

Parameters of function
The simplest way to obtain the parameters passed by the function caller is to use the zend_parse_parameters() function. We can directly generate the first few parameters of the zend_parse_parameters() function using macros in the kernel, in the form: ZEND_NUM_ARGS() TSRMLS_CC. Note that there is a space between the two, but there is no comma. As can be seen from the name, ZEND_NUM_ARGS() represents the number of parameters. The next parameter that needs to be passed to the zend_parse_parameters() function is a string used for formatting, just like the first parameter of printf. Several of the most commonly used symbols are represented below.
type_spec is a format string, its common meaning is as follows:
Parameter represents the type
b Boolean
l Integer
d Floating point
s String string
r Resource resource
a Array array
o Object instance Object
O Object instance of a specified type Object of a specific type
z Non-specific zval Any type ~
Z zval** type
f Represents function and method names. It seems that there is no such thing in PHP5.1... .. .
This function is just like the printf() function. The following parameters correspond to the format in the format string one-to-one. Some basic types of data will be directly mapped to types in the C language.
ZEND_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 is: %ldn", foo);
RETURN_TRUE;
}
Generally speaking, the data of the two data types int and long are often the same, but there are exceptions. Therefore, we should not put the long array in an int, especially on a 64-bit platform, which will cause some bugs that are not easy to troubleshoot. Therefore, when receiving parameters through the zend_parse_parameter() function, we should use variables of the types agreed by the kernel as carriers.
Parameter corresponds to the data type in C
b zend_bool
l long
d double
s char*, int The former receives the pointer, the latter receives the length
r zval*
a zval*
o zval*
O zval*, zend_class_entry*
z zval*
Z zval**
Note that all composite type parameters in the PHP language require the zval* type as a carrier, because they are some data structures customized by the kernel. We must confirm that the type of the parameter and the carrier are consistent. If necessary, it can perform type conversion, such as converting the array into a stdClass object. The s and O (capital letter European) types need to be talked about separately, because they both require two carriers. We will learn about the specific implementation of objects in PHP in the next chapters. So let's rewrite a function we defined in Chapter 5:
function sample_hello_world($name) {
echo "Hello $name!n";
}
When writing an extension, we need to use zend_parse_parameters( ) to receive this string:
ZEND_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( ; The execution will fail and FAILURE will be returned.
If we need to receive multiple parameters, we can directly list the receiving carriers in the parameters of zend_parse_paramenters(), such as:
function sample_hello_world($name, $greeting) {
echo "Hello $greeting $ name!n";
}
sample_hello_world('John Smith', 'Mr.');
This should be implemented in the PHP extension:
ZEND_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 ");
PHPWR ITE(greeting, greeting_len);
php_printf(" ");
PHPWRITE(name, name_len);
php_printf("!n");
}
In addition to the parameters defined above, there are three other parameters to enhance our ability to receive parameters, as follows:
Type Modifier Meaning
| The parameters before it are all required, and the parameters after it are optional, that is, they have default values.
! If you receive a null variable in PHP language, it will be directly converted into NULL in C language instead of encapsulating it into a zval of IS_NULL type.
/ If the passed variable shares a zval with other variables and is not a reference, it will be forced to separate. The new zval’s is_ref__gc==0, and refcount__gc==1.
The default value of the function parameter
Now let’s continue Rewrite sample_hello_world(), next we use the default values ​​​​of some parameters, which is like the following in PHP language:
function sample_hello_world($name, $greeting='Mr./Ms.') {
echo "Hello $greeting $name!n";
}
sample_hello_world('Ginger Rogers','Ms.');
sample_hello_world('Fred Astaire');
At this time, you can only pass one parameter to sample_hello_world, or you can Pass the complete two parameters. So how can we implement the same function in the extension function? We need to use the (|) parameter in zend_parse_parameters. The parameters before this parameter are considered necessary, and the parameters after this parameter are considered non-essential. If not passed, the carrier will not be modified.
ZEND_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");
}
If you do not pass the second parameter, the extension function will be considered as default without modifying the carrier. Therefore, we need to pre-set the value of the carrier ourselves, which is often NULL, or a value related to function logic. Each zval, including the IS_NULL type zval, needs to occupy a certain amount of memory space, and requires CPU computing resources to apply for memory for it, initialize it, and release it after they complete their work. But a lot of code doesn't realize this. There is a lot of code that wraps a null value into the IS_NULL type of zval. This operation can be optimized in extended development. We can receive the parameter as NULL in the C language. Let’s look at the following code on this issue:
ZEND_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) {
val = php_sample_make_defaultval(TSRMLS_C);
}
...
}
ZEND_FUNCTION(sample_arg_nullok) {
zval *val;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z! ",
                                                                                           val(TSRMLS_C);
}
}
The two pieces of code don't look very different at first glance, but the first piece of code does require more CPU and memory resources. Maybe this technique is not very useful in normal times, but it is better to know it than not knowing it.

Forced Separation
When a variable is passed to a function, whether it is referenced or not, its refcoung__gc attribute will be increased by one, becoming at least 2. One copy is itself and the other is the copy passed to the function. Before changing this zval, sometimes it is necessary to divide it into two actual copies in advance. This is the role of the "/" format character. It will split the copy-on-write zval into two complete and independent copies in advance, so that we can operate on it at will in the following code. Otherwise, we may need to constantly remind ourselves to separate the received parameters and other operations. Like the NULL flag, this modifier goes after the type it means to impact. Also like the NULL flag, you won't know you need this feature until you actually have a use for it.

zend_get_arguments()
If you want If your extension is compatible with older versions of PHP, or if you only want to use zval as a carrier to receive parameters, you can consider using the zend_get_parameters() function to receive parameters. zend_get_parameters() is different from zend_parse_parameters(). As we can see from the name, it obtains directly without parsing. First of all, it will not automatically perform type conversion. The carriers of all parameters in the extended implementation need to be of zval type. Let us look at the simplest example:
ZEND_FUNCTION(sample_onearg) {
zval *firstarg;
if { Do something with firstarg.. . */
}
Secondly, zend_get_parameters() will not throw an error by itself when receiving fails, nor can it conveniently handle parameters with default values. The last point is that it is different from zend_parse_parameters in that it will automatically forcefully separate all zvals that comply with copy-on-write, and generate a new copy and send it to the function. If you want to use its other features but don't need this function, you can try using the zend_get_parameters_ex() function to receive parameters. In order not to separate the variables of copy-on-write, the parameters of zend_get_parameters_ex() are of type zval** instead of zval*. This function is not used very often. You may only think of it when you encounter some extreme problems, but it is very simple to use:
ZEND_FUNCTION(sample_onearg) {
zval **firstarg;
if (zend_get_parameters_ex(1, &firstarg) == FAILURE) {
    WRONG_PARAM_COUNT;
  }
  /* Do something with firstarg... */
}
Note that zend_get_parameters_ex does not require ZEND_NUM_ARGS() as a parameter, because it is added at a later stage, and that parameter has already been No more.
The WRONG_PARAM_COUNT macro is also used in the above example. Its function is to throw an E_WARNING level error message and automatically return it.

Variable parameters
There are two other zend_get_parameter_** functions, which are specially used to solve the problem of many parameters or the number of parameters cannot be known in advance. Think about the usage of the var_dump() function in the PHP language. We can pass any number of parameters to it. Its implementation in the kernel is actually like this:
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);
}
The program first obtains the number of parameters, and then applies for a corresponding size of memory through the safe_emalloc function to store these zval** type parameters. The zend_get_parameters_array_ex() function is used here to fill the parameters passed to the function into args. You may have immediately thought that there is also a function called zend_get_parameters_array(). The only difference is that it fills zval* type parameters into args and requires ZEND_NUM_ARGS() as a parameter.

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
PHP in Action: Real-World Examples and ApplicationsPHP in Action: Real-World Examples and ApplicationsApr 14, 2025 am 12:19 AM

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

PHP: Creating Interactive Web Content with EasePHP: Creating Interactive Web Content with EaseApr 14, 2025 am 12:15 AM

PHP makes it easy to create interactive web content. 1) Dynamically generate content by embedding HTML and display it in real time based on user input or database data. 2) Process form submission and generate dynamic output to ensure that htmlspecialchars is used to prevent XSS. 3) Use MySQL to create a user registration system, and use password_hash and preprocessing statements to enhance security. Mastering these techniques will improve the efficiency of web development.

PHP and Python: Comparing Two Popular Programming LanguagesPHP and Python: Comparing Two Popular Programming LanguagesApr 14, 2025 am 12:13 AM

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

The Enduring Relevance of PHP: Is It Still Alive?The Enduring Relevance of PHP: Is It Still Alive?Apr 14, 2025 am 12:12 AM

PHP is still dynamic and still occupies an important position in the field of modern programming. 1) PHP's simplicity and powerful community support make it widely used in web development; 2) Its flexibility and stability make it outstanding in handling web forms, database operations and file processing; 3) PHP is constantly evolving and optimizing, suitable for beginners and experienced developers.

PHP's Current Status: A Look at Web Development TrendsPHP's Current Status: A Look at Web Development TrendsApr 13, 2025 am 12:20 AM

PHP remains important in modern web development, especially in content management and e-commerce platforms. 1) PHP has a rich ecosystem and strong framework support, such as Laravel and Symfony. 2) Performance optimization can be achieved through OPcache and Nginx. 3) PHP8.0 introduces JIT compiler to improve performance. 4) Cloud-native applications are deployed through Docker and Kubernetes to improve flexibility and scalability.

PHP vs. Other Languages: A ComparisonPHP vs. Other Languages: A ComparisonApr 13, 2025 am 12:19 AM

PHP is suitable for web development, especially in rapid development and processing dynamic content, but is not good at data science and enterprise-level applications. Compared with Python, PHP has more advantages in web development, but is not as good as Python in the field of data science; compared with Java, PHP performs worse in enterprise-level applications, but is more flexible in web development; compared with JavaScript, PHP is more concise in back-end development, but is not as good as JavaScript in front-end development.

PHP vs. Python: Core Features and FunctionalityPHP vs. Python: Core Features and FunctionalityApr 13, 2025 am 12:16 AM

PHP and Python each have their own advantages and are suitable for different scenarios. 1.PHP is suitable for web development and provides built-in web servers and rich function libraries. 2. Python is suitable for data science and machine learning, with concise syntax and a powerful standard library. When choosing, it should be decided based on project requirements.

PHP: A Key Language for Web DevelopmentPHP: A Key Language for Web DevelopmentApr 13, 2025 am 12:08 AM

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

SecLists

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.

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment