Premiers pas dans les extensions PHP



Documents pareils
Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Conventions d écriture et outils de mise au point

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Le prototype de la fonction main()

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

OS Réseaux et Programmation Système - C5

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Introduction au langage C

Programme Compte bancaire (code)

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

as Architecture des Systèmes d Information

Plan du cours. Historique du langage Nouveautés de Java 7

STS SE. FreeRTOS. Programmation réseau WIFI. Programmation réseau. Socket Tcp. FlyPort smart Wi-Fi module

Notions fondamentales du langage C# Version 1.0

Analyse de sécurité de logiciels système par typage statique

Argument-fetching dataflow machine de G.R. Gao et J.B. Dennis (McGill, 1988) = machine dataflow sans flux de données

Cours de C. Allocation dynamique. Sébastien Paumier

Cours d initiation à la programmation en C++ Johann Cuenin

Bases de programmation. Cours 5. Structurer les données

Programmer en JAVA. par Tama

Corrigés des premiers exercices sur les classes

M2-Images. Rendu Temps Réel - OpenGL 4 et compute shaders. J.C. Iehl. December 18, 2013

INFO-F-404 : Techniques avancées de systèmes d exploitation

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Introduction à la Programmation Parallèle: MPI

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

Arguments d un programme

Dis papa, c est quoi un bus logiciel réparti?

IFT Systèmes d exploitation - TP n 1-20%

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Algorithmique et Programmation, IMA

ACTIVITÉ DE PROGRAMMATION

Utilisation d objets : String et ArrayList

Généralités sur le Langage Java et éléments syntaxiques.

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Programmation Objet Java Correction

Java Licence Professionnelle CISII,

Corrigé des exercices sur les références

PHP et mysql. Code: php_mysql. Olivier Clavel - Daniel K. Schneider - Patrick Jermann - Vivian Synteta Version: 0.9 (modifié le 13/3/01 par VS)

2 Formation utilisateur

27/11/12 Nature. SDK Python et Java pour le développement de services ACCORD Module(s)

Derrière toi Une machine virtuelle!

TP1 : Initiation à Java et Eclipse


Programmation système I Les entrées/sorties

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Lambda! Rémi Forax Univ Paris-Est Marne-la-Vallée

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Stockage du fichier dans une table mysql:

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

Les chaînes de caractères

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

Les structures. Chapitre 3

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Java Licence Professionnelle CISII,

Intergiciels pour la répartition CORBA : Common Object Request Broker. Patrice Torguet torguet@irit.fr Université Paul Sabatier

Chapitre 10. Les interfaces Comparable et Comparator 1

Projet Viticulture - TP 3 : bases de données distantes BTS Services informatiques aux organisations

TD2/TME2 : Ordonnanceur et Threads (POSIX et fair)

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Tutoriel: Création d'un Web service en C++ avec WebContentC++Framework

Objets et Programmation. origine des langages orientés-objet

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Cours 1: Java et les objets

Chapitre 1 : La gestion dynamique de la mémoire

Extension SSO Java. Cette note technique décrit la configuration et la mise en œuvre du filtre de custom SSO Java.

Création d objet imbriqué sous PowerShell.

Package Java.util Classe générique

Langage Java. Classe de première SI

Configurer la supervision pour une base MS SQL Server Viadéis Services

7 Développement d une application de MapReduce

Auto-évaluation Programmation en Java

Environnements de développement (intégrés)

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

MapReduce. Malo Jaffré, Pablo Rauzy. 16 avril 2010 ENS. Malo Jaffré, Pablo Rauzy (ENS) MapReduce 16 avril / 15

Chapitre 2. Classes et objets

Le langage C. Séance n 4

Mysql. Les requêtes préparées Prepared statements

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Programmation en Java IUT GEII (MC-II1) 1

Programmation C++ (débutant)/instructions for, while et do...while

JADE : Java Agent DEvelopment framework. Laboratoire IBISC & Départ. GEII Université & IUT d Evry nadia.abchiche@ibisc.univ-evry.

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Programmation en langage C

Chapitre VI- La validation de la composition.

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

COMPARAISONDESLANGAGESC, C++, JAVA ET

Premiers Pas en Programmation Objet : les Classes et les Objets

Modélisation PHP Orientée Objet pour les Projets Modèle MVC (Modèle Vue Contrôleur) Mini Framework

Programmation Web. Madalina Croitoru IUT Montpellier

Projet de programmation (IK3) : TP n 1 Correction

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Introduction à JDBC. Accès aux bases de données en Java

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Transcription:

Premiers pas dans les extensions PHP Pierrick Charron, Confoo, Mars 2011 pierrick@php.net

Qui suis-je? Consultant TI à Montréal Auteur de l'extension PHP Stomp Contributeur PHP depuis 2009 Core RFC (Request For Comment) Documentation (Fr & En) Premiers pas dans les extensions - Pierrick Charron 2

Une extension? Premiers pas dans les extensions - Pierrick Charron 3

Pourquoi créer une extension? Permettre l'utilisation d'une librairie externe Exemple : mysql, curl Améliorer les performances Opération impossible dans l'espace utilisateur Exemple : Xdebug, operator, vld Satisfaire sa curiosité Premiers pas dans les extensions - Pierrick Charron 4

Avant de commencer Présentation basée sur PHP >= 5.3 Utilisation de Linux #include <stdio.h> void main() { printf("c Code"); } $ echo "terminal linux" terminal linux Premiers pas dans les extensions - Pierrick Charron 5

Prérequis Familier avec PHP Configuration de PHP Installation de modules Connaissances en C Patience API très complet Beaucoup, beaucoup, beaucoup... de macros Premiers pas dans les extensions - Pierrick Charron 6

Architecture de PHP API Serveur (SAPI) Apache FPM CLI Embed... Zend Engine PHP Core API pour les extensions standard mysqli curl date... Premiers pas dans les extensions - Pierrick Charron 7

Cycle de vie d'une extension Différentes étapes MINIT : Initialisation du module RINIT : Initialisation de la requête RSHUTDOWN : Arrêt de la requête MSHUTDOWN : Arrêt du module Moment et nombre d'appels dépend du SAPI Premiers pas dans les extensions - Pierrick Charron 8

Cycle de vie : CLI $ php monscript.php MINIT RINIT Execution du script RSHUTDOWN MSHUTDOWN Premiers pas dans les extensions - Pierrick Charron 9

Cycle de vie : Multiprocess MINIT RINIT Execution du Script RSHUTDOWN MINIT RINIT Execution du Script RSHUTDOWN RINIT Execution du Script RSHUTDOWN MSHUTDOWN RINIT Execution du Script RSHUTDOWN MSHUTDOWN Premiers pas dans les extensions - Pierrick Charron 10

Cycle de vie : Multithreaded MINIT RINIT Execution du Script RSHUTDOWN RINIT Execution du Script RSHUTDOWN RINIT Execution du Script RSHUTDOWN RINIT Execution du Script RSHUTDOWN MSHUTDOWN Premiers pas dans les extensions - Pierrick Charron 11

Zend Thread Safety / TSRM Utilisé avec des "threaded webservers" Chaque thread a son propre stockage local Evite les accès concurrents Premiers pas dans les extensions - Pierrick Charron 12

Les macros ZTS #define TSRMLS_D #define TSRMLS_DC #define TSRMLS_C #define TSRMLS_CC void ***tsrmls, TSRMLS_D tsrmls, TSRMLS_C static void ma_fonction(int i TSRMLS_DC); ma_function(10 TSRMLS_CC); static void ma_fonction(int i); ma_function(10); static void ma_fonction(int i, void ***tsrmls); ma_function(10, tsrmls); Premiers pas dans les extensions - Pierrick Charron 13

Zend Value Premiers pas dans les extensions - Pierrick Charron 14

ZVAL Zval : valeur dans espace utilisateur Attention valeur!= variable Conversion de type Compteur de référence Premiers pas dans les extensions - Pierrick Charron 15

ZVAL typedef struct _zval_struct { zvalue_value value; zend_uint refcount gc; zend_uchar type; typedef union _zvalue_value { zend_uchar is_ref gc; long lval; } zval; double dval; struct { char *val; IS_NULL int len; IS_LONG } str; IS_DOUBLE HashTable *ht; IS_BOOL zend_object_value *obj; IS_ARRAY } zvalue_value; IS_OBJECT IS_STRING IS_RESOURCE Premiers pas dans les extensions - Pierrick Charron 16

ZVAL typedef struct _zval_struct { zvalue_value value; zend_uint refcount gc; zend_uchar type; zend_uchar is_ref gc; } zval; Nombre de variables qui pointent vers cette valeur Définit si oui ou non une valeur est une référence Premiers pas dans les extensions - Pierrick Charron 17

ZVAL typedef struct _zval_struct { zvalue_value value; zend_uint refcount gc; zend_uchar type; zend_uchar is_ref gc; } zval; Nombre de variables qui pointent vers cette valeur Définit si oui ou non une valeur est une référence $a $b $a = 10; $b = $a; $b = 20; value.lval = 10 refcount = 2 type = IS_LONG is_ref = 0 Premiers pas dans les extensions - Pierrick Charron 18

ZVAL typedef struct _zval_struct { zvalue_value value; zend_uint refcount gc; zend_uchar type; zend_uchar is_ref gc; } zval; Nombre de variables qui pointent vers cette valeur Définit si oui ou non une valeur est une référence $a $b $a = 10; $b = $a; $b = 20; value.lval = 10 refcount = 21 type = IS_LONG is_ref = 0 value.lval = 20 refcount = 1 type = IS_LONG is_ref = 0 Premiers pas dans les extensions - Pierrick Charron 19

ZVAL typedef struct _zval_struct { zvalue_value value; zend_uint refcount gc; zend_uchar type; zend_uchar is_ref gc; } zval; Nombre de variables qui pointent vers cette valeur Définit si oui ou non une valeur est une référence $a $b $a = 10; $b = &$a; $b = 20; value.lval = 10 refcount = 2 type = IS_LONG is_ref = 01 Premiers pas dans les extensions - Pierrick Charron 20

ZVAL typedef struct _zval_struct { zvalue_value value; zend_uint refcount gc; zend_uchar type; zend_uchar is_ref gc; } zval; Nombre de variables qui pointent vers cette valeur Définit si oui ou non une valeur est une référence $a $b $a = 10; $b = &$a; $b = 20; value.lval = 10 20 refcount = 2 type = IS_LONG is_ref = 01 Premiers pas dans les extensions - Pierrick Charron 21

ZVAL : Récuperer le type #define Z_TYPE(zval) (zval).type #define Z_TYPE(zval_p) Z_TYPE_P(zval_p) Z_TYPE(*zval_p) #define Z_TYPE(zval_pp) Z_TYPE_PP(zval_pp) Z_TYPE(**zval_pp) zval foo; Z_TYPE(foo) == IS_LONG zval *bar; Z_TYPE_P(bar) == IS_BOOL Premiers pas dans les extensions - Pierrick Charron 22

ZVAL : Récuperer une valeur #define Z_LVAL(zval) #define Z_BVAL(zval) #define Z_DVAL(zval) #define Z_STRVAL(zval) #define Z_STRLEN(zval) #define Z_ARRVAL(zval) #define Z_OBJVAL(zval) #define Z_*_P(zval_p) #define Z_*_PP(zval_pp) (zval).value.lval ((zend_bool)(zval).value.lval) (zval).value.dval (zval).value.str.val (zval).value.str.len (zval).value.ht (zval).value.obj (*zval). (**zval). Premiers pas dans les extensions - Pierrick Charron 23

ZVAL : Assigner une valeur ZVAL_NULL(zval); ZVAL_LONG(zval,l); ZVAL_DOUBLE(zval,d); ZVAL_STRINGL(zval,str,len,dup) ZVAL_BOOL(zval, b) Z_TYPE_P(zval) = IS_NULL; Z_TYPE_P(zval) = IS_LONG; Z_LVAL_P(zval) = l; l; Z_TYPE_P(zval) = IS_DOUBLE; Z_DVAL_P(zval) = d; Z_TYPE_P(zval) = IS_STRING; Z_STRLEN_P(zval) = len; if if (dup) { Z_STRVAL_P(zval) = estrndup(str, len+1); } else { Z_STRVAL_P(zval) = str; } Z_TYPE_P(zval) = IS_BOOLEAN; Z_BVAL_P(zval) = b? 1 : 0; Premiers pas dans les extensions - Pierrick Charron 24

Conversion void convert_to_string(zval *); void convert_to_long(zval *); void convert_to_double(zval *); void convert_to_null(zval *); void convert_to_boolean(zval *); void convert_to_array(zval *); void convert_to_object(zval *); Premiers pas dans les extensions - Pierrick Charron 25

Gestion de la mémoire Zend dispose d'un memory manager évite les fuites de mémoire signature des fonctions similaires aux fonctions natives C Premiers pas dans les extensions - Pierrick Charron 26

Les fonctions d'allocation Fonction C traditionnelle void *malloc(size_t count); void *calloc(size_t nmemb, size_t size); void *realloc(void *ptr, size_t size); char *strdup(const char *s); char *strndup(const char *s, size_t n); void free(void *ptr); Fonction spécifique à PHP void *emalloc(size_t count); void *ecalloc(size_t nmemb, size_t size); void *erealloc(void *ptr, size_t size); char *estrdup(const char *s); char *estrndup(const char *s, size_t n); void efree(void *ptr); Premiers pas dans les extensions - Pierrick Charron 27

Et les extensions alors? Premiers pas dans les extensions - Pierrick Charron 28

./ext_skel Outil de génération de code Génère le squelette de l'extension $./ext_skel --extname=monextension Premiers pas dans les extensions - Pierrick Charron 29

Les fichiers de monextension $ tree monextension monextension/ -- config.m4 -- config.w32 -- CREDITS -- EXPERIMENTAL -- monextension.c -- monextension.php -- php_monextension.h `-- tests `-- 001.phpt 1 directory, 8 files Fichiers de configuration Config.m4 Config.w32 Fichiers de code monextension.c php_monextension.h Premiers pas dans les extensions - Pierrick Charron 30

Config.m4 Script de configuration sous Linux Utilisé par./buildconf et phpize dnl If your extension references something external, use with: dnl PHP_ARG_WITH(monextension, for monextension support, dnl Make sure that the comment is aligned: dnl [ --with-monextension Include monextension support]) dnl Otherwise use enable: PHP_ARG_ENABLE(monextension, dnl whether whether to enable to enable monextension support, Make dnl Make sure sure that that the comment the comment is aligned: is aligned: [ dnl --enable-monextension [ Enable Enable monextension monextension support]) support]) Premiers pas dans les extensions - Pierrick Charron 31

Compiler monextension Dynamique $ phpize $./configure $ make $ make test Statique $./buildconf --force $./configure --enable-monextension $ make $ make test Premiers pas dans les extensions - Pierrick Charron 32

PHPT Avant même de commencer à programmer, pensez à écrire vos tests!!!! http://qa.php.net/write-test.php Premiers pas dans les extensions - Pierrick Charron 33

php_monextension.h Déclaration des données pour la liaison statique Premiers pas dans les extensions - Pierrick Charron 34

monextension.c #includes Structures statiques Fonctions PHP MINFO MINIT, MSHUTDOWN, RINIT, RSHUTDOWN Table des fonctions Définition du module Premiers pas dans les extensions - Pierrick Charron 35

Définition du module Structure permettant à PHP d'initialiser ou de désinitialiser le module zend_module_entry monextension_module_entry = { STANDARD_MODULE_HEADER, "monextension", monextension_functions, PHP_MINIT(monextension), PHP_MSHUTDOWN(monextension), PHP_RINIT(monextension), PHP_RSHUTDOWN(monextension), PHP_MINFO(monextension), "0.1", STANDARD_MODULE_PROPERTIES }; Premiers pas dans les extensions - Pierrick Charron 36

Liste des fonctions const zend_function_entry monextension_functions[] = { PHP_FE(confirm_monextension_compiled, NULL) {NULL, NULL, NULL} }; PHP_FE(nom, signature); PHP_FALIAS(nom, nom_original, signature); Premiers pas dans les extensions - Pierrick Charron 37

monextension.c Première fonction const zend_function_entry monextension_functions[] = { PHP_FE(monextension_helloworld, NULL) {NULL, NULL, NULL} }; /** **/ PHP_FUNCTION(monextension_helloworld) { php_printf("hello world!!!"); }; php_monextension.h PHP_FUNCTION(monextension_helloworld); Premiers pas dans les extensions - Pierrick Charron 38

PHP_FUNCTION PHP_FUNCTION(monextension_helloworld) { php_printf("hello world!!!"); } void zif_monextension_helloworld(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC) { php_printf("hello world!!!"); } Premiers pas dans les extensions - Pierrick Charron 39

Valeur de retour Modifier la variable return_value (zval *) Par défaut Z_TYPE_P(return_value) = IS_NULL Attention ne pas retourner la valeur! PHP_FUNCTION(monextension_helloworld) { ZVAL_STRING(return_value, "Hello world!!!", 1); return; }; Premiers pas dans les extensions - Pierrick Charron 40

RETVAL_* ZVAL Macro ZVAL_NULL(return_value); ZVAL_BOOL(return_value, bval); ZVAL_TRUE(return_value); ZVAL_FALSE(return_value); ZVAL_LONG(return_value, lval); ZVAL_DOUBLE(return_value, dval); ZVAL_STRING(return_value, str, dup); ZVAL_STRINGL(return_value, str, len, dup); ZVAL_RESOURCE(return_value, rval); RETVAL_* RETVAL_NULL(); RETVAL_BOOL(bval); RETVAL_TRUE(); RETVAL_FALSE(); RETVAL_LONG(lval); RETVAL_DOUBLE(dval); RETVAL_STRING(str, dup); RETVAL_STRINGL(str, len, dup); RETVAL_RESOURCE(rval); PHP_FUNCTION(monextension_helloworld) { RETVAL_STRING("Hello world!!!", 1); /* Code executé */ return; }; Premiers pas dans les extensions - Pierrick Charron 41

RETURN_* RETVAL_* n'interrompt pas l'exécution du code RETURN_* = RETVAL_*; return; PHP_FUNCTION(monextension_helloworld) { RETURN_STRING("Hello world!!!", 1); /* Code jamais executé */ }; Premiers pas dans les extensions - Pierrick Charron 42

Paramètres de fonction PHP_FUNCTION(monextension_helloworld) { char *name; int name_len; if (zend_parse_parameters(zend_num_args() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; } php_printf("hello %s!", name); }; Premiers pas dans les extensions - Pierrick Charron 43

Paramètres de fonction int zend_parse_parameters (int num_args TSRMLS_DC, char *type_spec,...) Spécificateur du type Type côté PHP Type de donnée côté C b Boolean zend_bool * l Entier long * d Virgule floatante double * s Chaine de caractère char **, int * r Ressource zval ** a Tableau zval ** o Objet zval ** O Objet d'un type spécifique zval **, zend_class_entry * z zval zval ** Premiers pas dans les extensions - Pierrick Charron 44

Paramètres optionnels Utilisation du modificateur " " PHP_FUNCTION(monextension_helloworld) { char *name = "world"; int name_len = sizeof("world")-1; if (zend_parse_parameters(zend_num_args() TSRMLS_CC, " s", &name, &name_len) == FAILURE) { return; } php_printf("hello %s!", name); }; Premiers pas dans les extensions - Pierrick Charron 45

Les tableaux (HashTable *) Stockage clef valeur Très rapide Combinaison de tableau C et de listes chaînées Utilisés presque partout dans le corp PHP Recherche par valeur impossible Premiers pas dans les extensions - Pierrick Charron 46

Initialiser un tableau int array_init(zval *z); /* $array = array(); */ PHP_FUNCTION(monextension_emptyarray) { array_init(return_value); }; Premiers pas dans les extensions - Pierrick Charron 47

Ajout d'éléments Tableau numérique Syntaxe PHP Syntaxe C $arr[1] = null; add_index_null(arr, 1); $arr[2] = "foo"; add_index_string(arr, 2, "foo", 1); $arr[3] = true; add_index_bool(arr, 3, 1); $arr[4] = 10; add_index_long(arr, 4, 10); $arr[5] = 3.1416; add_index_double(arr, 5, 3.1416); $arr[6] = $foo; add_index_zval(arr, 6, foo); $arr[] = null; add_next_index_null(arr); $arr[] = "foo"; add_next_index_string(arr, "foo", 1); $arr[] = true; add_next_index_bool(arr, 1); $arr[] = 10; add_next_index_long(arr, 10); $arr[] = 3.1416; add_next_index_double(arr, 3.1416); $arr[] = $foo; add_next_index_zval(arr, foo); Premiers pas dans les extensions - Pierrick Charron 48

Ajout d'éléments Tableau associatif Syntaxe PHP $arr["foo"] = null; Syntaxe C add_assoc_null(arr, "foo"); add_assoc_null_ex(arr, "foo", sizeof("foo")); $arr["bar"] = "foo"; add_assoc_string(arr, "bar", "foo", 1); add_assoc_string_ex(arr, "bar", sizeof("bar"), "foo", 1); $arr["baz"] = true; add_assoc_bool(arr, "baz", 1); add_assoc_bool_ex(arr, "baz", sizeof("baz"), 1); $arr["boz"] = 10; add_assoc_long(arr, "boz", 10); add_assoc_long_ex(arr, "boz", sizeof("boz"), 10); $arr["biz"] = 3.1416; add_assoc_double(arr, "biz", 3.1416); add_assoc_double_ex(arr, "biz", sizeof("biz"), 3.1416); $arr["buz"] = $foo; add_assoc_zval(arr, "buz", foo); add_assoc_zval(arr, "buz", sizeof("buz"), foo); Premiers pas dans les extensions - Pierrick Charron 49

Recherche d'éléments int zend_hash_find(const HashTable *ht, const char *arkey, uint nkeylength, void **pdata) int zend_hash_quick_find(const HashTable *ht, const char *arkey, uint nkeylength, ulong h, void **pdata) int zend_hash_index_find(const HashTable *ht, ulong h, void **pdata) zval **data; if if (zend_symtable_find(z_arrval(zval), "clef", sizeof("clef"), (void**)&data) == SUCCESS) { switch (Z_TYPE_PP(data)) { /*... */ } } Premiers pas dans les extensions - Pierrick Charron 50

Suppression d'éléments int zend_hash_del(hashtable *ht, char *arkey, uint nkeylen); int zend_hash_quick_del(hashtable *ht, char *arkey, uint nkeylen, ulong h); int zend_hash_index_del(hashtable *ht, ulong h); Premiers pas dans les extensions - Pierrick Charron 51

Création d'une classe zend_class_entry *counter_ce; PHP_MINIT_FUNCTION(monextension) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Counter", monextension_counter_methods); counter_ce = zend_register_internal_class(&ce TSRMLS_CC); zend_declare_property_long(counter_ce, "value", sizeof("value")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); return SUCCESS; } static zend_function_entry monextension_counter_methods[] = { PHP_ME(Counter, reset, NULL, ZEND_ACC_PUBLIC) PHP_ME(Counter, getvalue, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; Premiers pas dans les extensions - Pierrick Charron 52

Les méthodes PHP_METHOD(Counter, getvalue) { zval *object = getthis(); zval *details = NULL; details = zend_read_property(counter_ce, object, "value", sizeof("value")-1, 1 TSRMLS_CC); RETURN_LONG(Z_LVAL(value)); } PHP_METHOD(Counter, reset) { zend_update_property_long(counter_ce, getthis(), "value", sizeof("value")-1, 0 TSRMLS_DC) RETURN_TRUE; } Premiers pas dans les extensions - Pierrick Charron 53

Quelques outils bien utiles ;) Premiers pas dans les extensions - Pierrick Charron 54

Code compatible ZTS? Compilez toujours votre PHP avec --enable-maintainer-zts Premiers pas dans les extensions - Pierrick Charron 55

Fuites de mémoire? --enable-debug $ php -e <?php leak(); [Tue Feb 22 20:12:17 2011] Script: '-' /home/pierrick/php-src/trunk/zend/zend_builtin_functions.c(1425) : Freeing 0x7FA54892B708 (3 bytes), script=- === Total 1 memory leaks detected === $ Premiers pas dans les extensions - Pierrick Charron 56

Fuites de mémoire? valgrind $ USE_ZEND_ALLOC=0 valgrind --tool=memcheck --leak-check=yes --numcallers=30 --show-reachable=yes sapi/cli/php leak.php. ==7164== LEAK SUMMARY: ==7164== definitely lost: 0 bytes in 0 blocks ==7164== indirectly lost: 0 bytes in 0 blocks ==7164== possibly lost: 0 bytes in 0 blocks ==7164== still reachable: 1,111,059 bytes in 8,728 blocks ==7164== suppressed: 0 bytes in 0 blocks. Premiers pas dans les extensions - Pierrick Charron 57

Recherche de code? grep http://lxr.php.net Premiers pas dans les extensions - Pierrick Charron 58

Premiers pas dans les extensions - Pierrick Charron 59

Premiers pas dans les extensions - Pierrick Charron 60

Segfault? GDB (gnome debugger) $ gdb --args php -d extension=monextension.so segfault.php (gdb) r Starting program: /usr/local/bin/php -d extension=monextension.so segfault.php [Thread debugging using libthread_db enabled] [New Thread 0x7fffefd1f700 (LWP 9457)] [Thread 0x7fffefd1f700 (LWP 9457) exited] Program received signal SIGSEGV, Segmentation fault. strcpy_chk () () at../sysdeps/x86_64/strcpy_chk.s:196 196../sysdeps/x86_64/strcpy_chk.S: No such file or directory.in../sysdeps/x86_64/strcpy_chk.s (gdb) bt #0 strcpy_chk () () at../sysdeps/x86_64/strcpy_chk.s:196 #1 0x00007fffefd20b0c in strcpy (ht=<value optimized out>, return_value=<value optimized out>, return_value_ptr=<value optimized out>, this_ptr=0x6, return_value_used=0, tsrm_ls=0xfa70c0) at /usr/include/bits/string3.h:107 #2 zif_monextension_helloworld (ht=<value optimized out>, return_value=<value optimized out>, return_value_ptr=<value optimized out>, this_ptr=0x6, return_value_used=0, tsrm_ls=0xfa70c0) at /home/pierrick/php-src/trunk/ext/monextension/monextension.c:162 #3 0x00007ffff2658b35 in xdebug_execute_internal (current_execute_data=0x7ffff7eb7050, return_value_used=0, tsrm_ls=0xfa70c0) at /home/pierrick/installs/xdebug-2.1.0/xdebug.c:1339 #4 0x000000000081b777 in zend_do_fcall_common_helper_spec (execute_data=0x7ffff7eb7050, tsrm_ls=0xfa70c0) at /home/pierrick/php- Premiers pas dans les extensions - Pierrick Charron 61

Besoin d'aide? Irc.EFNet.org #php.pecl Mailing Lists http://marc.info/?l=php-internals http://marc.info/?l=pecl-dev Premiers pas dans les extensions - Pierrick Charron 62

Envie de lecture? http://www.php.net/manual/en/internals2.php Advanced PHP Programming par George Schlossnagle Extending and Embedding PHP par Sara Golemon ISBN#0-6723-2704-X Premiers pas dans les extensions - Pierrick Charron 63

Questions? pierrick@php.net Twitter: @adoyy Commentaires et présentation : http://joind.in/2869 Premiers pas dans les extensions - Pierrick Charron 64