


Explication détaillée d'exemples de passage de paramètres et d'obtention de paramètres dans la fonction d'extension de l'extension PHP
Avant-propos
Après la génération automatique du framework d'extension de l'extension PHP dans l'article précédent, j'ai une compréhension globale du framework d'extension PHP. En gros, on peut dire que j'ai une certaine compréhension. de la façon d'écrire des extensions PHP et les points clés Mais la clé réside dans la façon d'écrire la fonction PHP_FUNCTION.
Cet article enregistre principalement comment PHP transmet les paramètres lors de l'appel d'une extension et comment la fonction d'extension reçoit l'appel. Traitez-le comme votre propre mémo
Texte
1.zend_parse_parameters
Pour obtenir les paramètres transmis par la fonction, vous pouvez utiliser la fonction zend_parse_parameters. Les étudiants attentifs constateront que le. La fonction par défaut générée par le fonctionnaire est également Utilisez cette fonction pour recevoir les paramètres.
Comment utiliser cette fonction ?
Tout d'abord, vous pouvez utiliser ce livre en lisant comme le scanf de PHP. (Si vous n'êtes pas familier avec cette fonction, n'hésitez pas à lire ici)
zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, &参数1,&参数2…);
Le premier paramètre est le nombre de paramètres passés à la fonction. L'approche habituelle consiste à lui transmettre ZEND_NUM_ARGS(). (ZEND_NUM_ARGS() pour exprimer "autant qu'il y a de paramètres" transmis) Il s'agit d'une macro qui représente le nombre total de paramètres passés à la fonction.
Le deuxième paramètre concerne la sécurité des threads, transmettez toujours la macro TSRMLS_CC.
Le troisième paramètre est une chaîne qui spécifie le type de paramètre attendu par la fonction, suivi d'une liste de variables qui doivent être mises à jour avec la valeur du paramètre. Puisque PHP est un langage faiblement typé, il utilise des définitions de variables lâches et un jugement de type dynamique, tandis que le langage C est fortement typé, et zend_parse_parameters() sert à convertir différents types de paramètres dans le type attendu. (Lorsque la valeur réelle ne peut pas être forcée dans le type attendu, un avertissement sera émis)
Les quatrième, cinquième et nième paramètres sont toutes les valeurs des valeurs à transmettre.
Explication détaillée du troisième paramètre
Concernant le troisième paramètre, voici une liste de paramètres parmi lesquels choisir :
类型指定符 | 对应的C类型 | 描述 |
---|---|---|
l | long | 符号整数 |
d | double | 浮点数 |
s | char *, int | 二进制字符串,长度 |
b | zend_bool | 逻辑型(1或0) |
r | zval * | 资源(文件指针,数据库连接等) |
a | zval * | 联合数组 |
o | zval * | 任何类型的对象 |
O | zval * | 指定类型的对象。需要提供目标对象的类类型 |
z | zval * | 无任何操作的zval |
Il y a deux points qui nécessitent une attention particulière ici
1. Le type c correspondant au type chaîne a ici deux paramètres. Oui. Cela montre que lorsque vous utilisez la fonction zend_parse_parameters(), vous devez l'utiliser comme ceci :
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&name, &name_len)
L'un représente le contenu de la chaîne et l'autre est la longueur de la chaîne.
2. J'ai besoin de savoir brièvement, qu'est-ce que zval ?
zval est le conteneur de valeurs du moteur Zend. Que la variable soit un booléen, une chaîne ou tout autre type, ses informations sont toujours contenues dans une union zval. Jetons un coup d'œil à la structure de zval :
typedef union _zval { long lval; double dval; struct { char *val; int len; } str; HashTable *ht; zend_object_value obj; } zval;
ps : je n'expliquerai pas typedef car j'ai trouvé que quelqu'un l'avait déjà très bien écrit. Veuillez cliquer ici pour un résumé de l'utilisation de typedef<. 🎜>
Le bord implique également trois utilisations supplémentaires pour améliorer notre capacité à recevoir des paramètres :“|”和”!”将在下文有具体例子讲解,关于”/”虽然大概懂意思,但没想到具体的例子。
走一波与php的交互
正常的样子
在PHP中
<?phpfunction my_function($msg) { echo "我收到参数啦: {$msg}!\n"; } my_function('咖啡色的羊驼');
如果my_function写成PHP扩展:
ZEND_FUNCTION(my_function) { char *msg; int msg_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&msg, &msg_len) == FAILURE){ RETURN_NULL(); } php_printf("我收到参数啦:"); PHPWRITE(msg, msg_len); php_printf("!\n"); }
两个参数的样子
在PHP中
<?phpfunction my_function($email, $msg) { echo "我收到参数啦: {$email}、 {$msg}!\n"; } my_function('123456@qq.com', '咖啡色的羊驼');
如果my_function写成PHP扩展:
ZEND_FUNCTION(my_function) { char *email; int email_len; char *msg; int msg_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&msg, &msg_len,&email, &email_len) == FAILURE){ RETURN_NULL(); } php_printf("我收到参数啦:"); PHPWRITE(email, email_len); PHPWRITE(msg, msg_len); php_printf("!\n"); }
两个参数,其中一个可选且有默认值
<?phpfunction my_function($email, $msg = '咖啡色的羊驼') { echo "我收到参数啦: {$email}、 {$msg}!\n"; } my_function('123456@qq.com');
如果my_function写成PHP扩展:
ZEND_FUNCTION(my_function) { char *email; int email_len; char *msg = "咖啡色的羊驼"; int msg_len = sizeof("咖啡色的羊驼") - 1; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s",&msg, &msg_len,&email, &email_len) == FAILURE){ RETURN_NULL(); } php_printf("我收到参数啦:"); PHPWRITE(email, email_len); PHPWRITE(msg, msg_len); php_printf("!\n"); }
这里说明了”|”的使用
参数为null时,省内存的写法
先来不省的写法
ZEND_FUNCTION(my_function) { zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z",&val) == FAILURE) { RETURN_NULL(); } }
省内存
ZEND_FUNCTION(my_function) { zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!",&val) == FAILURE) { RETURN_NULL(); } }
这里例子用上了”!”,每个zval,包括IS_NULL型的zval,都需要占用一定的内存空间,需要cpu的计算资源来为它申请内存、初始化,并在它们完成工作后释放掉。但是很多代码都都没有意识到这一点。有很多代码都会把一个null型的值包裹成zval的IS_NULL类型,在扩展开发里这种操作是可以优化的,我们可以把参数接收成C语言里的NULL。
所以就差了一个!,第二个例子就更省了内存。
2.zend_get_arguments()
用法
例子是最好的用法讲解,上例子:
ZEND_FUNCTION(my_function) { zval *email; if (zend_get_parameters(ZEND_NUM_ARGS(), 1, &email)== FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"至少需要一个参数"); RETURN_NULL(); } // ... }
区别与特点
1.能够兼容老版本的PHP,并且只以zval为载体来接收参数。
2.直接获取,而不做解析,不会进行类型转换,所有的参数在扩展实现中的载体都需要是zval类型的。
3.接受失败的时候,不会自己抛出错误,也不能方便的处理有默认值的参数。
4.会自动的把所有符合copy-on-write的zval进行强制分离,生成一个崭新的copy送到函数内部。
综合评价:还是用zend_parse_parameters吧,这个函数了解下即可,不给力。
3.zend_get_parameters_ex()
用法
ZEND_FUNCTION(my_function) { zval **msg; if (zend_get_parameters_ex(1, &msg) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"至少需要一个参数"); RETURN_NULL(); } // ...}
不需要ZEND_NUM_ARGS()作为参数,因为它是在是在后期加入的,那个参数已经不再需要了。
区别与特点
1.此函数基本同zend_get_parameters()。
2.唯一不同的是它不会自动的把所有符合copy-on-write的zval进行强制分离,会用到老的zval的特性
综合评价:极端情况下可能会用到,这个函数了解下即可。
zend_get_parameter_**
这个包括:zend_get_parameters_array_ex()和zend_get_parameters_array()
用法
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<argc; i++) { php_var_dump(args[i], 1 TSRMLS_CC); } efree(args); }
这个有点复杂,需要解释一下:
程序首先获取参数数量,然后通过safe_emalloc函数申请了相应大小的内存来存放这些zval**类型的参数。这里使用了zend_get_parameters_array_ex()函数来把传递给函数的参数填充到args中。
是的
这个参数专门用于解决像php里面的var_dump的一样,可以无限传参数进去的函数的实现
区别与特点
1.用于应对无限参数的扩展函数的实现。
2.zend_get_parameters_array与zend_get_parameters_array_ex唯一不同的是它将zval*类型的参数填充到args中,并且需要ZEND_NUM_ARGS()作为参数。
综合评价:当遇到确实需要处理无限参数的时候,真的要用这个函数了。zend_parse_parameters真的做不到啊~
总结
抛开一切,最少也要学会zend_parse_parameters()的用法。好的。扩展函数传参数的技能get了。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

PHP 8.4 apporte plusieurs nouvelles fonctionnalités, améliorations de sécurité et de performances avec une bonne quantité de dépréciations et de suppressions de fonctionnalités. Ce guide explique comment installer PHP 8.4 ou mettre à niveau vers PHP 8.4 sur Ubuntu, Debian ou leurs dérivés. Bien qu'il soit possible de compiler PHP à partir des sources, son installation à partir d'un référentiel APT comme expliqué ci-dessous est souvent plus rapide et plus sécurisée car ces référentiels fourniront les dernières corrections de bogues et mises à jour de sécurité à l'avenir.

Si vous êtes un développeur PHP expérimenté, vous aurez peut-être le sentiment d'y être déjà allé et de l'avoir déjà fait. Vous avez développé un nombre important d'applications, débogué des millions de lignes de code et peaufiné de nombreux scripts pour réaliser des opérations.

Visual Studio Code, également connu sous le nom de VS Code, est un éditeur de code source gratuit – ou environnement de développement intégré (IDE) – disponible pour tous les principaux systèmes d'exploitation. Avec une large collection d'extensions pour de nombreux langages de programmation, VS Code peut être c

JWT est une norme ouverte basée sur JSON, utilisée pour transmettre en toute sécurité des informations entre les parties, principalement pour l'authentification de l'identité et l'échange d'informations. 1. JWT se compose de trois parties: en-tête, charge utile et signature. 2. Le principe de travail de JWT comprend trois étapes: la génération de JWT, la vérification de la charge utile JWT et l'analyse. 3. Lorsque vous utilisez JWT pour l'authentification en PHP, JWT peut être généré et vérifié, et les informations sur le rôle et l'autorisation des utilisateurs peuvent être incluses dans l'utilisation avancée. 4. Les erreurs courantes incluent une défaillance de vérification de signature, l'expiration des jetons et la charge utile surdimensionnée. Les compétences de débogage incluent l'utilisation des outils de débogage et de l'exploitation forestière. 5. L'optimisation des performances et les meilleures pratiques incluent l'utilisation des algorithmes de signature appropriés, la définition des périodes de validité raisonnablement,

Ce tutoriel montre comment traiter efficacement les documents XML à l'aide de PHP. XML (Language de balisage extensible) est un langage de balisage basé sur le texte polyvalent conçu à la fois pour la lisibilité humaine et l'analyse de la machine. Il est couramment utilisé pour le stockage de données et

Une chaîne est une séquence de caractères, y compris des lettres, des nombres et des symboles. Ce tutoriel apprendra à calculer le nombre de voyelles dans une chaîne donnée en PHP en utilisant différentes méthodes. Les voyelles en anglais sont a, e, i, o, u, et elles peuvent être en majuscules ou en minuscules. Qu'est-ce qu'une voyelle? Les voyelles sont des caractères alphabétiques qui représentent une prononciation spécifique. Il y a cinq voyelles en anglais, y compris les majuscules et les minuscules: a, e, i, o, u Exemple 1 Entrée: String = "TutorialSpoint" Sortie: 6 expliquer Les voyelles dans la chaîne "TutorialSpoint" sont u, o, i, a, o, i. Il y a 6 yuans au total

Liaison statique (statique: :) implémente la liaison statique tardive (LSB) dans PHP, permettant à des classes d'appel d'être référencées dans des contextes statiques plutôt que de définir des classes. 1) Le processus d'analyse est effectué au moment de l'exécution, 2) Recherchez la classe d'appel dans la relation de succession, 3) il peut apporter des frais généraux de performance.

Quelles sont les méthodes magiques de PHP? Les méthodes magiques de PHP incluent: 1. \ _ \ _ Construct, utilisé pour initialiser les objets; 2. \ _ \ _ Destruct, utilisé pour nettoyer les ressources; 3. \ _ \ _ Appel, gérer les appels de méthode inexistants; 4. \ _ \ _ GET, Implémentez l'accès à l'attribut dynamique; 5. \ _ \ _ SET, Implémentez les paramètres d'attribut dynamique. Ces méthodes sont automatiquement appelées dans certaines situations, améliorant la flexibilité et l'efficacité du code.
