Vous êtes sur la page 1sur 10

f

e .ffi Mr ir!i, s& *ji$ *'*, * o, <w 'd6 ,*$'W&

ZendAPI - créezvotre propre


extensionpour PHP
Niveau de difficulté : oro
Marcin Staniszczak

Votrescript est trop lent ? ll vous sembleque


I'originese trouve dans I'efficacitéde PHP?
Ou peut-êtrevoulez-vousvous connecterà une
autreapplicationou utiliservotre bibliothèque
favorite en langageG ? ZendAPI peut vous
aider à résoudrevos problèmes.

end API est une interface pour GodeGen_PECL


les programmeurs.Elle permet - préparez-vousau travail
d'écriredes extensionspour PHP Créer une extensionsd-même est une
en langageC. Afin d'écrirede très simples tÉlchetrès compliquée.La premièreétape
extensions,il suffit de connaîtreles ba- d'implémentrationest particulièrement
ses de ce langage; vous verrez dans la complexe.Heureusement, à présent,vous
suitede cet articleque les outilsgénérant ne devezplusvousen préoccuperdansla
le modèle entier d'une telle extension plupartdes cas. ll suffitpar exempled'uti-
à votreplacesontdéjà disponibles. En ce liser CodeGen_PECL.D'après le fichier
qui concemeles programmesplus avan- XML où vous décrivezI'extensioncréée,
és, il faudra bien connaftrele langage ce script génère pour vous tous les 11-
C et avoir des tialentsde détectivescar chiersindispensables ainsique le modèle
certainsélémentsde Zend API sont très d'extension(débutd'un fichier sourceen
peu documentés.ll sera donc nécessaire C où vous ajoutezensuitela fonctionnalité
Marcin Staniszczak est étudiant en W- d'analyserles souroes des extensions
mière année d'informatique des études
foumiesavecPHP.
æmplémentaires de maîtise à WSHE Ce qu'il faut savoir...
(Académie de Science éænomiques et Pour les besclinsde cet artide, nous ll sera nécessairede connaltreles bases
socrb/es) à Lodz. ll prognmme en PHP céerons ensembleune extensionpouraiot- des langagesC et PHP.
depuis de nombrcuses années. // esf ter à PHPunefundinn,permettiant de calcu-
auteur de plusieurc publications æn-
cemant PHP. ll a @nçu un fnmewod<
lerde simplesfrcrmules mahérnathues;elle Cet articleexplique...
contiendrades opérationsélémentaires,par Commentréaliserune extensionpour
MVC pur PHPS (web.fnmewotu) ef
PHPà I'aidede ZendAPI; cetteexten-
un système de modèles pur PHPS exemple=, -, *, ott z. ll estégalementpossi-
(web.template).
sion permetta d'efiec'tuerde simples
ble d'utiliserlibrementbs parenhèses( t r ) mathématiques.
opérations
e t l æ c r o c h e b ( r: ) .

www.phpsolmag.org N'5/2006
PHPSolutions
prévue).Cette démarchepermet d'éco- de générerune table avec des informa- de placer les deux balises immédiate-
nomiserbeaucoupde tempset de stress tions; elle s'afficheradans la page re- ment en dessousde la balise ouvrante
que vous perdrezen tentantd'effectuer tournéepâr phpinroo . Le scriptcharge < e x t e n s i o n > .
toutce travailvous-même. le nom de I'extensiondepuis le para- La balise (maintainers> Coîtehant la

Avant d'écrireI'extensionà I'aidede mètre namede la balise <extension>. Si balise (mainrainer) (décrivantchaque
XML,il faut installerle script CodeGen_ vous voulez placer une brève informa- concepteur)est responsablede placer
PECL.ll est possiblede le faire de plu- tion dans phpinfoo concernantI'exten- les informations sur les concepteursde
sieursmanières.Si vous disposezd'une sion (résumé),placez-laà I'intérieurde I'extension (Listing1). Une telle descrip-
connexionInternet,il est recommandé la balise <summary> i tion comprendson nom (par exemple
d'efiectuerla commandesuivanteau ni- le pseudonyme),placé dans la balise
veaudu terminal: <summary> <user>,le nom et le prénomplacésdans
Exemple de Lrextension PHP - RPN la balise<name>, I'adressede message-
pear install -o Codegen_PECL </ surunary> rie électronique,placée dans la balise
<emair> et le rôlequ'iljouedansl'équipe
Cette commandepermetde télécharger ll faut placerde manièreanalogueI'infor- de personnesresponsables du travailsur
et d'installerle script.Si vous n'avezpas mationprincipalesur I'extensiondans le I'extension; cettedernièreinformationse
de connexionIntemet,regardezle CD bloc <oescriprion>.Les concepteurs du trouvedans la balise<role>. La balise
joint au magazine:il contientles archi- script CodeGen_PECL recommandent (mainrainers) peut bien évidemment
ves avec le script,version1.0.0.Afin de
l'installer,passez au répertoirecontenant Démarragerapide
ces archiveset effectuezles commandes Vous pouvezdétjàvoir le résultatdu fonctionnementde I'extensioniciprésentée.N'oubliez
suivantes: pgs toutefoisque vous aurez besoindu système Unix (p. ex. Linux ou FreeBSD)pour la
compiler.En théorie, les sources contiennentles fichiers du projet pour Visual Studio, gé-
nérés automatiquementpar le script CodeGen_PECL; son concepteur n'a pas testé s'il
pear install CodeGen-1.0.0.t92
était possiblede compilercette extensionsous Windows.
pear install CodeGen-PECL-l.0.0.t92 Afin d'efiectuer la compilation,vous devez disposer de PHP et des fichiers d'en-tête
installés(les fichiersavec l'extension.h utilisésdans les programmesécrits en G) ainsi
que du compilateurC et des outils associés(gcc, make etc.).
Cettecommandepermetde bien installer
Afin de compiler I'extensiondans votre système, copiez ses sources dans votre dis-
le scriptCodeGen,nécessaireà un fonc- que, allez dans le répertoireavec I'extensionet tapez la commandesuivante :
tionnementconect par CodeGen_PECL
et parCodeGen_PECL. phpize; ./configure; make; sudo make install

Si, quand vous efiectuezcette commandemake insratl, vous obtenezI'informationsur


Commentdécrire une ereur (absencede droits,autrementdit, d'une entrée appropriéedans le fichier su-
l'extensionà
I'aidede XML? doers), connectez-vousau système en tant que root et efiectuezde nouveau la comman-
Une fois le script codeGen_pEcr instiallé, ds make insrarr aprèss'êtredéplaé dans le répertoireavec les sourcesde I'extension.
Une fois I'extensioncompiléeet installée,il faut configurerPHP en ajoutantla ligne
créezle fichierXML avec la descriptionde
suivanteau fichierphp.ini :
votreextension.
La descriptionde I'extensionse trou- e x t e n s i - o n = R P Ns. o

vera dans la balise <exrension>. Cette


Assurez-vous que la directive extension_dir dans php.ini est conectement paramétrée
baliseprendun paramètrequi est le nom et qu'elleindiquele répertoireoù make insralr a copié I'extension.Voici commentcela
de I'extensioncréée. Appelonscette ex- se présentechez moi :
tensionRPN - de ReversePolish Nota-
= "/usr/Ioca1/php5
tion - le nom de la méthodeutiliséepar extension dir /Iib/php/ extensions/"

I'extensionpour calculerI'expression(elle ll suffit à présentde redémaner le serveur HTTP pour que tout fonctionnebien.
seratransforméeau formatde la Notation
PolonaiseInverse et calculée ensuite; NotationPolonaiselnverse
vous trouverez davantaged'informations La notationpolonaiseinverse est une méthodespécifique,permettrantd'écrire les formules
mathématiques.Puisqu'ony insère le caractèrede I'opérationefrectuéeaprès les opéran-
sur NPf dans I'encadrêNotationPolonaise
des, les parenthèsesdeviennentinutiles.À titre d'exemple,I'expression:
lnverse).Placez donc la descriptionde
I'extensionà I'intérieur
du blocsuivant: ,]-5-5)/2

est écrite sous forme de :


<extension name="RPN">

<!-1a description de I'extension

sera placée ici-->


</extension>
Le site de Wikipedia vous propose davantage d'informationssur NPI et sur des algorith-
mes de transformationdes expressionsà partir de I'entrée infixée (traditionnelle)en NPI
et d'afgorithmes,permettant de calculer des expressions ainsi transformées: httpl/fr.
D'aprèsles informationsdu fichierXML, wikipedia.oryfit iki/N otationjol onaise_i n ve rse
le script CodeGen_PECLest capable

N'5/2006
PHPSolutions wwwphpsolmag.org
contenir plusieurs blocs (maintainer)
E gil Ur lpdûûb lod 51P avec les descriptionsde chaque membre
Ël*r.' I E. de l'équipe.
--
itr.?, ttg ZLù-*.tlff1gl.tr@..4? ------ - - [ s [ i G - e * o " * ' . r , &i 6ô Ajoutez à présent I'informationsur la
version de votre extension. Pour ce fai-
r e , v o u s d i s p o s e zd u b l o c < c h a n s e l o g >
contenant les balises <retease>qui dé-
crivent chaque version. ll est possible
de décrire chaque édition à I'aide du
numéro placé dans la balise (versi.on),
de la date d'édition placée dans la
balise (dare>, du statut d'édition (par
exemple beta, stable etc.) dans la bali-
sê <srate> et de la descriptiond'édition
placée dans la balise <nores>.Le bloc
<chanseros>peut contenir la description
de plusieurs versions. Le Listing 2 pre-
sente la description de l'édition de votre
æ.rlon
extension.
Dans pnpinro o , il est Possible de
placer une image mais vous pouvez par-
Figure 1. Exempled'informationsurfertension,généréed'aprèslesdonnées fois avoir des problèmes pour I'afficher
contenuesdansle fichierXML correctement. Si vous voulez le tenter,
utilisez la balise <roso>. Cette balise
prend deux arguments I src QUi est le
des membresde l'équipequitravaillentsur l'ertension
Listing 1. Description
nom du fichier avec I'image et mimetype
..maintainers). qui déterminele Wpe MIME de I'image(il
est possible d'omettre ce paramètre, en
.maintainer.,
ce qui concerne les images au format gif,
. u s e r . . S t a n i s z c z a k . /t u s e r . ,
' n a m e .M a r c i n S t a n i s z c z a k / n a m e
png ou jpeg car le script CodeGen-PECL
. e m a i ] . ' m a r c i n G s t a n i s z c z a k . p I . / e m ai I : est ici capable de reconnaÎtre le type de
, r o l e : ' l - e a d ' :/ r o l e : ' I'image):
, /maintainer:

( 1 o g o s r c = " c a 1 c .g i f "
.:!-vous pouvez placer ici plus de blocs maintainer --:
mimetype=" image / gif" / >
, /maintainers:,

Listing 2. Description .' cesinformaflonssonf utilisées


de l'éditionde I'extension La balise(ticense) est très intéressante
;
lorsde l'affichagedu numérode Ia versiondansphpinfoQ. elle permetd'ajouterdes informations sur
nh: naa l nn
la licence aux fichiers sourcesde I'ex-
, release:' tensionet de générerle fichierLICENSE
r.version-'0 . 0 . 1../version.: avec le texte de la licence.Cette balise
, r d a t e : . 20 O6 - 0 3 - 2 0 . : / d a t e ; . peut prendreen ce momentles valeurs
. :s t a t e ; , b e t a . :/ s t a t e : '
' . - n o t e sr P r e m j - è r e v e r s i o n b ê t a < / n o t e s . '
, / release t CodeGen_PECL
Voustrouverezle scriptCodeGen_PECL
<J-- vous pouvez placer ici la description d'autres éditions, en 'les dans le répertoirePEAR. Auparavant,il
décrivant de la nêne rnanière gue ci-dessus--> s'appelaitPECL_Genet faisait partiedu
,../change I og:-' répertoirePECL. Ce scriptaide considé-
rablementà créer des extensionspour
Listing 3. Desciptionde la fonctionde l'extensioncréée PHP en générantd'aprèsle fichierXML
les modèles complets d'extensions.
, f unction n a m e = "r p n _ c a f c u f a t i o n " . ' La documentation CodeGen PECL
..Proto>float rpn-calculation(string phrase) /proto,' se trouve à l'adresse suivante hftpl/
.'./f unction -' p hp - b a u steII e. d e/Co d e G e n-P E CL/
<f unction n a m e = "r p n _ e r r o r m s g " > manual.htm; en ce qui concerne
<Proto>string rpn errormsg O../Proto> I'extension à proprement parler, vous
< r /f u n c t i o n >
pouvez la télécharger soit à I'aide
< . fu n c t i o n n a m e = "r p n _ e r r o r " . >
du programme pear qui fait partie de
.'Proto;.booI rpn_errormsg O . /Proto>
PHP soit depuis le site lnternet hftpl/
pe a r. ph p. n et/p ackage/Cod e G e n-
.:/function:,
PECUdownload.

www.phpsolmag.org PHP SolutionsN" 5/2006


de prototypesde
PHP,BSD ou LGPL; il traiteles autres Tableau1. Typesde donnéesautoiséesdans les descriptions
valeurscommeinconnueset il est alors fonctionsdansle fichierXML
incapablede générerdes donnéesap-
propriées.
Typ logiqueprenantlesvaleurstrueet false
La Figure1 présenteI'informationde
phpinfoO survotreextension.
Le script CodeGen_PECLajoute Typenumérhue- à virguleflottant
toujoursI'encadréavec les informations
sur les variables,
demandées par I'exten-
sion et paramétréesau niveaudu fichier
php.ini.
ll est temps de réfléchiraux fonc-
tions qui seront nécessairesdans votre Typede donnéesmixte
extenSion. PrenOnS rpn calculation ()
qui calcule la valeur de I'expression,
rpn_errormsq O gui afficheuneéventuelle
information sur I'erreuret rpn_errorQUi
retournetruelfalseen fonctionde la pré-
sence ou de l'absenced'erreur.Seule
la fonctionrpn_calcurationprendraun Tableau2. Fonctions rnfernesde ZendAPI
paramètreet toutes les fonctionsretour-
neront les valeurs. Décrivez donc les
fonctionsdans le fichier XML de sorte MINIT Unefonctionqui iniûalisel'extension. Elleest appeléeunefois,imm&
que le scriptCodeGen_PECL puissegé- diatement apÈs le démanagedu modulePHPzur le serveur.
nérer pour vous leurs modèles; vous
les compléterezavec le code. Pour ce
faire,utilisezla balise<function),prenant
le paramètrêname, qui est le nom de la
fonction créée. Le nom seul ne suffit Cettebncton est appeléeavantchaqueexécufiondu scriptPHPcnt
pas. ll faut en plus déclarer le proto- aprèsla bncfion MlNtf, en oe qul concameles scrlpûcCGI6t CLl.
type de fonctions,contenantI'information
sur le type des données retournées
et le nom et le type des paramètres pris.
Le Listing3 présenteun exempledécri- MINFO Cettebnc{on est appeléepar phplnl$loru de l'sfrdngp deo h6r-
vantvos troisfonctions. rnationeeur I'extension.Elle est charyéed'afifier lencadÉ avecbt
infurmations.
Commevous pouvezle constater,les
prototypesde fonctions- placéesdans la
balise(proro) - ressemblent aux décla- Listing 4. Déclarationsdes corpsde fonctionsdirectementdansle fichierXML
rationsde fonctions en C. lls difièrentpar
,tfuncEion role-"internaL" name-"RINIT".,
les nomsde types.Le Tableau1 présente .:code )
les nomsde typesautorisés. .:! ICDATAI
ll est possiblede placerdirectement m e m s e t( e r r o r M e s s a g e , 0 , 2 5 5 l 'i
le code en C dans les descriptionsde lsError - 0i

fonctions.À titre d'exemple, j'ai placé


Int s - RPN_G(rpn_stack_slze);
dans le fichier XML un code pour les
stack lnltlalize (s) ;
fonctionsspécialesZend APl, nrnrr et
RSHUTDowN. Ces fonctionssont appelées s - R P N _ G ( r p n _ q u e u e _ e L z ei l
de manièreautomatique respectivement q ueue_lnltlaILze(al;

avantet aprèsI'exécution du scriptPHP ll>


'-:/code >
ou, en ce qui concerneles scriptsCGI et , ,/ f u n c t l o n ; '
CLl, immédiatement aprèsle démarrage
de PHP (le Tableau2 présenteune des- <functlon role-"lnternaI" n a m e - " R S H U T D O I {)N "
criptionplus détailléedes fonctionssys- < c o d e>
< I I C D À T À[
tèmes).Sivous voulezdéfinirle corpsde
stack free 0 ;
la fonctionspéciale,utilisezle paramètre
queue_free ( ) ;
rOlede la balise(funcrion) i paramétrez il.,
sa valeurinrernar et le nom de la fonc- ,:/code>

tion en une des valeursqui se trouvent .:/funcELon;'

dans le Tableau2. Le Listing4 présente

PHPSolutions
N'5/2006 www.phpsolmag,org
peut prendre I'une des valeurs pré-
Tabfeau3. Valeursquepeutprendrele paramètreaccessde la balise<phpini>: où
peuton modifierla valeurde la variabledonnée ? sentées dans le Tableau3.

Le Listing 5 présente un exemple de dé-


claration de deux variables modifiées au
System La valeur de la variable peut âbe paramétréedans le fichier php.ini ou dans
la configurationdu serueurHTTP niveau du fichier php.ini.
La description placée entre la balise
ouvrante et fermant€ <phpini> est uti-
Larraleurde la variablepeutôtremodiliéedansle codePHP lisée lorsque CodeGen_PECL génère
la documentation au format DocBook
(comme d'autres informations du fichier
xML).
VotrefichierXML est donc Prêt.Si
un exemple de déclarationdu corps des .hfaccessou la configurationHTTP); vous voulezen savoirdavantagesur Co-
fonctionsRrNrr et nsHuroowN. il faut ici attribuerles valeursunique- deGen_PECL,reportez-vous à I'encadré
Remarquez que le code de la ment aux variablesnumériques,les CodeGenPECL.
fonction a été placé dans la balise valeursd'autrestypes sont attribuées Lorsquele fichierXML est prêt, il est
( c o d e >e t f e r m é d a n s l a s e c t i o n c D A T A dansla fonctionRlNlT, temps de générer les cadres de votre
du langage XML : il faut utiliser la o n u p dare nom de l a méthode extensiond'aprèsce fichier.Ouvrezune
s e c t i o n c D A r Ap o u r q u e l e p a r s e r X M L à appelerlors de changementde fenêtreterminal(console)et tapezla com-
ignore les erreurs XML, provoquées valeurs; si vous ne précisezpas ce mandesuivantedans le répertoireoù se
par les caractères placés dans le paramètre,la méthode par défaut trouvele fichierXML:
code. Vous pouvez également utiliser o n u p datestri ns ; i l est
S êrâuti l i sée
la balise <code> dans les foncti.ons possible d'utiliserici la méthode pecl-gen nom du fichier.xml

déclarées par vous-mêmes (p.ex. onupdarerYp où TYP est le nom du


dans vos fonctions rpn calcuration, type du Tableau1 (écrit en majus- Si tout se passecorrectement, le script
r p n - e r r o r m s g€ t r p n - e r r o r ) . C ' e s t t r è s cules), il est égalementpossible doit créer un nouveau répertoire portant
pratiquepour du code simple, comme de donner le nom de votre Propre le même nom que votre extension ;
celui du Listing 4. Si le code devient fonctionmais il faut alors la définir il devraitcontenirtous les fichiers.ll est
toutefois plus complexe (comme par vous-même (vous trouverez Plus donc tempsde commencerà Program-
exemple le code de la fonction rpn_ d'informationssur ce sujet dans la mer !
carculation), il est recommandé de suite de cet article,hélas, le script 3.r
demander au script CodeGen-PECL CodeGen_PECLne peut pas vous Ecrrre le programme
d e g é n é r e r s e u l e m e n tl e m o d è l e d e l a y aider), Regardezà présentle contenudu réper-
fonction et d'écrire le code dans votre access informationprécisantoù toire générépar le script.Deux fichiers
é d i t e u r o u e n v i r o n n e m e n td e d é v e l o p - I'utilisateur peut paramétrerla valeur importantss'y trouventparmi de nom-
pement préféré. d'unevariabledonnée; ce paramètre breux fichiers: RPN.c et php-RPN.h.
ll vous reste à déclarer les varia-
bles paramétrées au niveau du fichier
php.ini. Dans cet article, ces variables Listing 5. Déclaration des vaiables dont la valeur est modifiable au niveau du
fichier php.ini
déterminerontla taille de la pile et de
la queue, utilisées lors de la transfor- .:globals
mation de I'expression mathématique :phpini name="rpn_stack_size" type="rnt" value="50"
onupdate="OnupdateLong" access="perdi r".'
en Notation Polonaise Inverse et lors
laille de Ia pile utitisée pour les cafculs.
de calculs. Ces variables s'appelle-
. /phpini
ront respectivement rpn_stack_size
et rpn_queue_sizeE . n ce qui con- ' phpini n a m e = " r p n _ q u e u e _ s i z e "t y p e = " i n t ' r v a l u e = " 1 5 0 "
cerne les variables paramétrées au onupdate="OnUpdateLong" access="perdir">
TaiIIe de la queue utilisée pour les calcufs.
niveau de php.ini, définissez-les dans
, /phpini
l e b l o c ( s t o b a l s ) , e n u t i l i s a n tl a b a l i s e
. /globals '
<phoini>. La balise <phpini> prend 5
paramètres: Listing 6. Définitiondes fonctionsproposéespar l'extension

RPN_functionslI .
function_entry
name- est le nom de la variable,
PHP_FElrpn_caIcuIation, NULL)
rype - détermine le type de la varia-
P H P _ F E( r p n _ e r r o r m s g , NULL)
ble (voir le Tableau 1), P H P _ F E( r p n _ e r r o r , NULL)
varue - détermine la valeur que doit , NULL, NULL, NULL ,
prendre la variable si elle n'est pas
définie dans le fichier php.ini (ou

www.phpsolmag.org PHP SolutionsN'5/2006


'z

Ouvrez maintenantle fichier RPM.c Tableau4. Macrosqui seruentà définirles fonctions


avec lui et ensuite,
car vous travaillerez
cherchez la fonction rpn calcuration ZEbID_FE {nafte, arg_types) Définltion de la forcfion appekâe name. Le
le nom.
d'après paramètre ars_t1pes doit tgujours êbe
configuréà NULL. La-bndion ainsidédarÉe
Fonctions sera t iHe Bn PHP egre ls norn de nameêt
elle appellera la bncffon C zif_name
rpn calculation se trouve dans deux
endroits;tout d'abord,dans le tableau
RpNfuncrions êt ensuite,en tant que
définition de la fonction (la définition
ne vous rappelle probablementpas
le langageC - nousen parlerons dansla
suitede I'article)- sanscompterles com-
mentairesqu'a ajouté CodeGen_PECL. ZEND_FALIAS (name, alias' arg_t1pes) Cette macro #frnlt lalbs appelé arias dans
Commevous pouvezle remarquer,les la fonc'tion PHP appelê€ name.ars_t1æes
trois fonctionsde votre extensionsont d€vrait ête srfigur6à NULL.
définiesdans le tableau: Listing6. Les
élémentsdu tableauqui décrit les fonc-
tionssontdu type function_entryi ce ty-
pe est une structureà troischamps.Mais
nous ne nous en occuperonspas. Afin
de définir les fonctions,utilisezle script ramètres et leur nombre pris par la paramerers. Le nombrede paramètres de
CodeGen_PECL, comme nous I'avons fonction n'ont pas été déterminésde eættefonctionest variable.Son en-têtese
déjà présenté,ou les macros,par exem- panière typique. Heureusement,vous présentede manièresuivante:
ple, PHP_FE, comme le fait CodeGen_ disposez de la macro zEND_NUM_ARGS
PECL. ll est possibleque vous devrez qui retournele nombre de paramètres i n t z e n d _ p a r s e _ p a r a m e t e r s
ajouter parfoisvous-mêmeune fonction transmisaux fonctions.ll est possible r i nf nrrn âr^c Tszu{LS
\ rrr DC,
e !. grrl

à I'extension,il faut donc connaîtreles de les utiliserpour vérifiersi le nombre char* type spec, ... )

macros qui vous facilitentcette tâche. d'argumentstransmisdu scriptPHP est


Le Tableau4 présentetoutesles macros correct.Si ce n'est pas le cas, appelez Le premierargumentest le nombrede
supportant la définition des fonctions. la macrowRoNG_pARAM_couNr pour termi- paramètrestransmis à la fonction lors
N'oubliez pas que {Nult, NULL, lrull} ner le fonctionnement de la fonctionet de son appel.Le deuxièmeargumentest
doitêtrele dernierélémentdu tableaudu afficher I'informationsur I'erreur,simi- une suitede caractèresqui décritle type
Listing6. laireà celle-ci: de paramètresattenduspar la fonction.
La déclarationà proprementparler Waming:Wrongparametercountfor Ensuite se trouvent les variablesdans
de la fonction n'est pas typique pour lesquellesles paramètresseront enre-
le langage C. La macro pHp_FUNcrroN r p n _ c a l c u l a t i o n i n gistrés.Le deuxièmeparamètre,la suite
a été utiliséepour la déclaration ; cette /home/marcin/public html/test. php de caractèresdécrivantles paramètres,
macrocommuniqueavec la macropsp_ on line 3 est assez important.Cette suite peut se
FE (lorsque vous utilisez les macros composerdes caractèressuivants:
du groupezEwo,il faut utiliserla macro Le code, généré par CodeGen_PECL
zEND_FUNcrrou analogue à pHp_ruNcrroN pour analyser les paramètresdonnés . r - détermineque la variabledoit être
afin de déclarerles fonctions).Comme lors de I'appeldes fonctionsdepuis le du type lons âVêCce caractère,
vous le voyez sur le Listing7, les pa- scriptPHP,utilisela fonctionzend_parse_ . d - détermineque la variabledoitêtre
du type doubreavecce caractère,
. s - détermineque la'variabledoit
Listing 7. Déclarationdes fonctionsrpn_calculation
être du type strine avec ce ca-
P H P F U N C T I O N ( r p nc a l c u l a t i o n ) ractère mis à part I'entrée, la
fonction zend _ parse _ parameters
const char * phrase = NULL; retourneégalementsa longueur(au
int phrase_Ien = 0;
paramètresuivant dans la liste des
( ) TSRI,ILS_CC,"s/" ,
(zend_parse_parameters (ZEND_NUM_ARGS
paramètres d'appel de la fonction
if
&phrase, &phrase 1en) == FAILURE) i zend - parse - parameters),

retsurn; . b - détermineque la variabledoit être


du type booreanavecce caractère,
p h p _ e r r o r ( E _ W A R N I N G ," r p n _ c a l c u l a t i o n : not yet implemented"); RETURN_FALSE; . r - détermineque la variableindique
R E T U R ND O U B L (EO .O ) ;
la ressource (en anglais .esource)
avec ce caractère - elle retourne
la valeurdu type zval*,

PHP SolutionsN'5/2006 www.phpsolmag.org


Tabteau5. Macrosqui retournentla valeurde la fonction: ilfaut les utiliserdans/es Lorsque vous créez des fonctions
fonctionscrééesà la place des instructionshabituellesreturnvaleur disponibles du niveauPHPen ZendAPl,
n'oubliezpas de retournerles valeurs
(resource)
RETURN RESOURCE auxressources
Elleretoumeun indicateur à l'aide des macros adéquates.Ces
macrossont chargéesde bien convertir
la valeurretournéepour qu'ellepuisse
RETURN NULLO Elle retoumeune valeurNULL
être interprétéecorrectementpar Zend
Engine. Le Tableau5 présentetoutes
RETURN DOUBLE(double) Elleretoumeun nombreà viçule flottant les macros qu'il est possibled'utiliser
pour retournerles valeurs à partir de
fonctions.
L'appeld'une fonctionPHP du ni-
RETURN STRINGL(string, length' Elle retoumeune entréedont la longueur veau de votre extensionest souvent
duplicate) est déterminée par le deuxièmeparamètre. utile et facilitede nombreusestâches.
Le troisièmeparamètredéterminesi l'entrée ll est impossible de le fairede manière
doit être dupliquée.Cette macro est plus naturellecomme nous I'avonsfait en
rapidequeRETURN_STRING.
appelant les fonctions écrites en C.
Heureusement, la fonctioncaLL_user_
Elleretorne la valeurfaux runcri onest di sponi bldans
e Ze ndAPl.
Voicison en-tête:

int call- user function (

a - détermineque la variabledoit être il serait retournédans la variable,pla- H a s h T a b L e *f u n c t i o n table,

un tableau avec ce caractère -.elle cée dans la liste de paramètresde la zrr:l ** nhioni-
v v J v v e
nn
r f l
Zva].* fUnCtiOn name,

retourne la valeur du type zva).*, fonction zend parse parametersderrière zvaL* retval_ptr, zend_uint param_count,

o - détermineque la variabledoit être phrase_ren. Le caractère o fonctionne zv:l* naramstl TSRMLS


DC )

un objet de n'importe quelle classe de manière similaire, à cette différence


avec ce caractère - elle retourne la près que le deuxième paramètre n'est Les paramètressemblentêtre compli-
valeur du type zvar*, pas utilisé pour enregistrer la longueur qués mais heureusement, tout est plus
o - détermine que la variable doit mais pour lire le type demandé de la simplequ'il ne le semble.Regardezle
être I'objet de la même classe que classe. Listing8. C'est un fragmentde la fonc-
la classe du paramètre dans la liste Après s'être arrêtée, la fonction zend_ tion .p.t_calcuLation, chargé de rem-
d'appels de la fonction zend_ parse _ parse parameters rgtourne la valeur placertous les crochetsde I'expression
paramerers (ce paramètre ne sera succESS en cas de réussiteet rarlune si mathématique en parenthèses. Comme
pas utilisé pour stocker les valeurs une erreur survient (en cas d'erreur, elle vous le voyez,dans I'appelde la fonc-
du paramètre suivant transmis au retourne la valeur appropriée et affiche ti on, I' appelde l a macrocG(f unct i- on_
script PHP - un autre paramètre de un avertissement, par exemple, sur le rabre) constituele premierparamètre.
la liste de paramètres sera utilisé pour type incorrect des paramètres à I'utilisa- Cette macro retourne les tableaux
ce but) - il retourne la valeur du type teur du script). de fonctions d'après son paramètre.
zva l*,

z - p?rârr'tètre de n'importequel type Listing 8. Déclaration de la fonction rpn_calculation


- il retournela valeurdu type zval*,
r ( bar r ev er t ic a l e )-s i g n i fi eq u e l e s zval func;
zval 'params 3j;
autres paramètresseront faculta-
tifs, M À K ES T D Z V À L i p a r a m s0i l ) ;
z - signifieque la valeurdu paramè- MAKE STD ZVAL(params r 1 ) ;
tre précédentdoit être copiée et ne M A K ES T D Z V A L ( p a r a m s i 2 ) ;

pastransmisepar la référence,
Z V A L S T R I N Gr ' ,f u n c ,
"str replace"
r - signifieque le paramètreprécé-
Z V A L S T R I N G ( p a r a m0s , i l [ " , 0 ) ;
dentpeutprendrela valeurNULL. Z V A LS T R I N G ( p a r a n s ' 1 ' ", ( " , 0 ) ;
Z V A L S T R I N G ( p a r a m s ' 2, p h r a s e , 0 ) ;
Les valeurs o et s pêuVêît être à I'origine calI_user_function ( C G( f u n c t i o n _ t a b I e ) ,
(zvaL")NULL, , r f u n c , / , p h r a s e f 3 , p a r a n s T S R M L SC C ) ;
de doute car elles utilisentdeux paramè-
tres. Si vous utilisez la valeur s, cofillrlê
Z V A L S T R I N G ( p a r a m s i 0 l ," 1 " , 0);
le présente le Listing 7, aussi bien I'en- Z V A LS T R I N G ( p a r a m s i l l ", ) " , 0);
trée (dans la variable phrase) que sa Z V A L S T R I N G ( p a r a m s i 2 l ,p h r a s e , 0 ) ;
longueur (dans la variable phrase_ren) c a L l u s e r f u n c t i o n ( C G (f u n c t i o n t a b L e ) ,
( z v a l { - ) N U L L , &f u n c , t p h r a s e , 3 , p a r a m s T S R M L S _
seront retournées. Si la fonction atten-
dait un autre paramètre après I'entrée,

www.phpsolmag.org PHP SolutionsN" 5/2006


Le deuxième paramètre a obtenu la va- Tabfeau 6. Macros qui attibuent une valeur appropiée à la variable du type zval
leur uull, car il est importantseulement - premier paramètre de la macro est toujours le nom de la variable du type zval
quand la fonction appelée soit une mé-
thode d'un objet. Puisque nous avons ZVAL RESOURCE(2, 1) Elle attribuela valeurde la ressourceà la variablezvar.
besoin de la fonction str replace, coh- Le paramètreI est une valeur du type long
figurez ce paramètre à la valeur Nulr,.
Le paramètre suivant est un nom de la
variable où doit être enregistréle résul- Z V A L F A L S E( z ) Elle est équivalente à l'appel de la
tat de I'exécutionde la fonctionappelée. BOOL(2,0)
lci, il s'agit de la variable phrase donc
la même qui subit le fonctionnement
de la fonction. Les deux derniers ZVAL NULL(z) Elle attribuela valeurNULLà la variablezvar
arguments de la fonction carr_user_
funcrion sont: le nombre de Paramè-
tres à transmettre à la fonction appelée ZVAL DOUBLE(2, d) Elleattibue la valeurdu type doubleà là variablezval, cet-
et le tableau contenantces paramètres. te valeur est tansrnise dans le deuxièmepanamèbe(d).
Vous avez déjà probablementremar-
qué que la plupart des paramètresatten-
dus par la fonction call_user_function
sont du typê zvar. ll faut donc les créer
correctement.Une fois le paramètre dé-
ZVAL STRINGL(2, s, 1, dup) Elle attribue la valeur du type string (entrée) à la va-
riable zvar. Les paramètres: s - suite de caractères
claré, il faut I'initialiseravant de lui attri- char*,l- longueurde la suitede caractères,dup - s'il a
buer une valeur. La macro MAKEsrD zvAL la valeur 1, la variabledoit êtnecopiée,s'il a 0, elle doit
y contribue. Ensuite, une fois la variable être transmisepar une référence
initialisée, vous pouvez lui attribuer sa
valeur, en utilisant les macros du groupe ZVAL ZYAL(2, zv, dup, dtor) Elle copie une variablê zval dans une autre. Le pa-
zvAL NoMDUrvps. Le Tableau 6 regroupe ramètre dup détermine si la valeur doit être copiée ou
et décrit en détails ces macros. transmise par une référence.Le paramètrê dtor déter-
mine si la variablesource (zv) doit être supprimée(1)
Le premier appel de la fonction scr_
après la copieou pas (0).
reprace, remplaçantle crochet t en ( en
PHP se présenteraitainsi :

$ p h r a s e= s t r _ r e p l a c e ( ' [ ' , ' ( ' , $phrase),' typef pval zval,'

typedef struct _zval_struc zval;


lci, vous aviezbesoinde 10 lignes.Re-
marquezaussiqu'audeuxièmeappelde typedef union _zvalue value t
la fonctionstr_reptace(qui remplacele long lval; /*l-ongh, resourc, bool*/
doubfe dval,' /* double *,/
crochetI en )), il n'est pas nécessaire struct { /*s|Lring */
lesvariables.
d'initialiser char *val,'
Le type zvat êst utiliséparZendAPI : int len;
) str;
toutesles variables,sur lesquelles opère HashTable *ht; /* array */
PHP,sont de ce type. Pour con-
travailler struct l* / ob)ect " /
zend class entry *ce;
fortablement, il faut disposer également tl: clrTah l a *nrnncrl- i eq :

des fonctionsqui convertissent le contenu I obj;


les différentstypes supportés ) zvalue val-ue;
zvar dâîs
par PHP (par exemPle convert_to_
boolean_extzt). Regardez également la
Figure 2 qui présentela structurezvar #define IS NULL
#defi-ne IS LONG
vous pourez
(lorsquevous la connaîtrez, #define IS DOUBLE
utiliserseschamps). #define IS BOOL
#define IS ARRÀY
#define IS OBJECT
Fonctions spéciales Zend API #define IS STRING

Ce que vousavezconnujusqu'àprésent #define IS RESOURCE


#define TS CONSTANT
vous permettra d'écrire des extensions #define 15 CONSTANT ARRAY

assez complexes.Regardezmaintenant #define IS CONSTANT INDEX

les fonctionsspécialesZend API (rappe-


lez-vouscommentvous avez configuré
lesfonctionsintemesde ZendAPI à I'aide Figure 2. Créerla structurczval- en PHE toufesles valeursde variablessontdu type
de XML- Tableau2). De mêmeque pour zval

N'5/2006
PHPSolutions www.phpsolmag.org
les fonctionsproposéespar I'extension, où sont déclarées les variables globales. derniersparamètressont des structures
lesfonctionsinternesde ZendAPI doivent Les paramètres de la macro sont les qui décriventlesvariables globalesde vo-
être déclaréesavantI'utilisation dans une suivants: nom de la variable sous lequel tre application ; vous ne devez pas vous
structureadéquate.Regardezdonc les elle doit être modifiée au niveau du fichier en préoccuper car même si vous voulez
Listings9 et 10. Commevous le devinez php.ini; la valeur de la variable à utiliser ajouter manuellement la variable modi-
probablement,la structurezend_modure_si elle n'est pas envoyée dans le fichier fiée au niveaudu fichierphp.ini,lesdeux
enrry sert à écrireI'extension créée.Ses php.ini; la manière d'accès à la variable derniersparamètresrestenttels que les a
premierschampssonttoujoursremplacés (valeurspossibles: pnp_rNr_sysrEM, pHp_ générésle scriptCodeGen_PECL.
par la macro sTANDARD_MoDULE_HEADRES, INI USER, P H P I N I A I I E t P H P I N I P E R DIR ll anive parfois que vous voudriez
les autres champs constituentle nom Tableau 3). Un autre paramètre est le écrire votreproprefonctionexécutéeauto-
de I'extension, qui est, dans cet article, nom de la méthode à appeler au moment matiquement lors de la modification de la
npr.r. Ensuite,précisezle nom du tableau de la modification de la valeur de la va- valeur de la variable avec php.inl. C'est
décrivant les fonctions proposées par riable. Les fonctions standards de gestion une tâche très simple et consiste à utiliser
I'extension(cettestructures'appelledans d'événement de I'actualisationsont dis- une macroappropriéelors de la réalisa-
cet article RpN_funcrions Listing 6). - ponibles. Elles s'appellent onupdateryp, tion de la fonction:
Les cinq autres champsde la structure où typ est le nom du type de la variable :
constituentles déclarationsde fonctions L o n g , S t r i n g , B o o l , D o u b l - e e t C . L g C i n - PHP INI MH(OnChangeQueueSize)

intemesde l'extension, respectivement: quième paramètre de la macro est une t


M I N I T , M S H U T D O V ù NR,T N T T , R S H U T D O W NE t variableglobalequi doit obtenirla valeur z e n d _ p r j - n t f ( " V a l e u r R P M r. p n _ q u e u e _ s i z e

MrNFo. Si I'unede ces fonctionsest inu- de la variabledu fichier php.ini. Les deux s ' é l - è v e à % s c b r > " , n e w v a l - u e );

tile dans votre extension,remplacezla


macro du groupe eHe_ajoutée lors de Listing 9. Structurequi décritvotre extensionet lesfonctionsintemesde ZendAPI
générationdu fichiersourceen C par le
scriptCodeGen_PECL par la valeuruçrli,. zend_modufe_entry RPN_module_entry - .
STANDARDMODULEHEADER,
Tous les autres champsde la structure ' ,R P N , '
,
serontcomplétéspar I'appelde la macro DDlrT frrnnt i nnc

STANDARDMODULE PROPERTIES. P H P M T N I T ( R P N ),

Les définitionsdes fonctionsintemes PHP MSHUTDOWN(RPN),

ont été généréespar la macroCodeGen_ PHP RINIT (RPN),


(RPN) ,
PHP RSHUTDOWN
PECL. De même que pour le code des
PHP MINFO(RPN),
fonctionsproposéespar votre extension ,rn n t,l

et pourlesfonctionsintemesde ZendAPl, STÀNDARD MODULE PROPERTIES

desfonctionsestcrééeà I'aide
la définition ,

desmacrosappropriées. Cesmacross'ap-
pellent PHP_nomDeFonction_FUNcTroN, Où
Listing 10. Sfrucfurede zend_module_entry
le nomde la fonction,c'estrespectivement typedef struct zend_module_entry;
_zend_modufe_entry
MINTT, MSHITDOWN, RINIT, N S H U T O O ME
It

MrNFo.La fonctionMrNFo a été déjàgéné- struct zend module entry :

rée par le script,il est toutefoispossiblede unsigned short size;


unsigned int zend_api;
I'analyseret de modifierle code généré.
unsigned char zend_debug;
Votre extensionutiliseen plus les fonc- unsigned char zts;
tionsnrNrr et nsnuroowlr la
afin d'initialiser char *name;
pileet les queues,utiliséeslorsde calculs zend_function_entry * functions;
int - m o d u l e _ s t a r t u p _ f u n c ) ( I N I T _ F U N C _ A R G ;S )
(nrurr) et ensuitede libérerles ressources 1
i n t ( * m o d u l e s h u t d o w n - f u n c ) ( S H U T D O W N - F U N C - A R; G S )
utiliséespar ces structures(nsHuroowN).
int ('request_startup_func1 ( I N I T _ F U N C _ A R G ;S )
Si vousvous le rappelez,le corpsde ces int 1' request_shutdown_func) (SHUTDoWN_FUNC_AR
; GS)
fonctionsa été déterminéau niveaudu void 1* info_func; ( ZEND_M0DULE_INF0_FUNC_ARGS)
;
fichierXML. char *version;
ld'autres éléments de la structurel

Variables php.ini
ll ne vous manqueque les optionsde lec- Listing 11. Vaiables configurables déclarées à l'aide des macros sonf chargées
ture de valeursde variablesconfigurables au niveau de php.ini
au niveau du fichierphp.ini.Ces varia-
PHPINI BEGIN()
bles sont déclaréesà I'aidedes macros
( "YR P N .r p n _ s t a c k _ s j .z e " ,
STD_PHP_INI_ENTR " 5 0" , PHP_INI-PERDIR,
(Listing11).
OnUpdateLong, rpn_stack_size, zend_RPN_gIoba1s, RPN-g1obals1
La macro srD PHPrNr ENTRY dit ( "YR P N .r p n _ q u e u e _ s i z e " ,
STD_PHP_INI_ENTR " 15 0" , PHP_INI_PERDIR,
à PHP quelle variable globale doit être OnUpdateLong, rpn_queue_size, zend_RPN_g1obals, RPN-globa1s1

modifiée au niveau du fichier php.ini P H PI N I E N D { )


- regardez le flchier d'en-tête php_RPN.h

www.phpsolmag.org PHP SolutionsN" 5/2006


queue,en ajoutantdeux lignessupplé-
Êb Eû Ur{ lodqnr*l Iot tl* au fichierphp.ini:
mentaires
lJ n*e.e. i E'
gtr <ts "r ,t 2 I *jtatp'r/l*l,taa,o,2riîtch/rDn,Cr & G';.,qi.t.t,n & æ p D À l r n n c r : n l r < i z o = r : i l l o d e l r n i l e

r.ll{ 1625
r22+[(98/32).r RPN.rpn queue size =

taill,e de Ia queue
Erprcrrion: Crlculrtr

Si tout se déroule correctement,vous


devriez lancer I'exempled'application
PHP qui utilisevotre extension(voir la
Fi gure3).

Pourterminer
Cet articlen'a pas tout dit sur la réalisa-
tiondes extensionspourPHP.L'absence
d'une bonne documentation rend sûre-
ment la vie difficile.D'un autre côté, un
grand nombre d'extensionsstandards
disponiblesavec les sources PHP ce
qui aide beaucoupà écrirevos propres
extensions.ll faut toutefoisêtre préparé
Figure 3. Fonctionnement d'un exemple d'application qui utilise l'extension créée à analyserle code étranger,par exem-
ple, les paramètrespris par la macroqui
return SUCCESS; fonction à appeler lors de la suppression vousintéresse.
) de variables. Si vous vous intéressezau sujet des
ll ne faut pas oublier non plus d'ini- extensionset vous voulez approfondir
Comme vous pouvez le constater,la tialiserla macro REGTsTER rNr ENTRTES o vos connaissances dans ce domaine,je
nouvellevaleuresttransmisedansla va- dans I'appel de la fonction MrNrr et les vous inviteà modifierdans un premier
riablenewvat-ue.Bienévidemment, pour macros uNREGTsTER rNr ENTRTES
o dans temps I'extension créée.Elle a été créée
que cettefonctionsoitappeléeautomati- la fonctionMSHUTDowN. volontairement de manièreà pouvoirla
quementaprès la modificationde la va- Maintenant,vous pouvez appeler les modifierà votreguise.Commencezà éh-
leur qlrel,e_size, plâcêz son nom en tant variables globales à l'aide de la macro minerI'option de la pileet de
d'initialisation
que le quatrièmeparamètrede la macro N O M D E L E X T E N S I O GN ( n o m d e l - a v a r i a b l e ) la queuede sorteque leurtailles'adapte
srD_pHp_rNr_ENrRy. est souvent d O n C n p u _ c ( n o m d e f a v a r i a b l e ) - f ê S â f -
Puisqu'il aux besoins(cettetâchen'estpas difficile
nécessaire d'avoiraussila longueurde dez le Listing4 ; on y appelle les variables en C). Ensuite,vous pouvezmodifierle
la nouvellevaleur(p.ex. lorsqu'ils'agit r p n _ s t a c k _ s i z e ê t f p n _ q u e u e _ s i z e d a n s l e code de sorteque la pile et la queuene
d'uneentrée),nous présentonsci-après code de la fonctionRrNrr et nsnuoowx. retiennentpas les valeursdu type doubr-e
de la macroPHPrNr MH:
la définition ou char mais immédiatement les valeurs
Compilation zvalde PHP.r
#define PHP INI MH (name) et lancement
*entry, Testez à présent votre extension.
int name(php ini entry
Sur Internet
char *new value, Grâce aux fichiersgénéréspar le script
uint new value fenqth, CodeGen_PECL, la compilationet I'instal- . http://www.php.neUmanual/en/
*mh arg1, lationsont très simples.Ellesconsistent internals.php - informationssur
void
ZendAPI qui se trouventdans la
void *mh arg2, void *mh arg3) à exécuterlescommandes suivantesdans
documentationofficielle PHP
contenantI'extension
le répertoire : - assez modestes,hélas
Les paramètresde la fonction créée . http://somabo.de/talks/- docu-
à I'aidede cettemacrosontles suivants: phpi ze ments provenantdes conférences
diversesconcernantPHP - vous y
la structuredécrivantla variable,la nou- . / c o n f i g u r e
trouverezdeux bonnesprésenta-
vellevaleurde la variable,la longueurde m a k e tions sur la questiondes exten-
la variableet trois argumentsfacultatifs s u d o m a k e i . n s t a l l s i o n sp o u r P H P
qui ne sontpas pourI'instantimportants. . http://www.zend.com/php/
intern aIs/exte nsi on -writing 1.p hp
Avant de chargerles variablesdéfi- Maintenant, il suffit d'ajouter une ligne - premièrepartiedu tutoriel
nies ci-dessus,il faut appelerla macro demandant de charger l'extension dans expliquantcommentécrireles
zEND rNrr MoDULEGLoBALSdans la fonc- le fichier php.ini (dans I'exemple d'ex- extensionsà I'aidede Zend API
tension, cette ligne se présente ainsi : . http://www.zend.com/php/
tion r,rrrurr.Cette macro prend trois para-
internaIs/extensi on -writing2.p hp
mètres : le nom de I'extension (ici, c'est extension:RpN.so)et de redémarrer le - deuxièmepartiedu tutorielsus-
nex), le nom de la fonction à appeler lors serveur HTTP. ll est également possible mentionné
de variableset le nom de la
d'initialisation de modifier la taille de la pile et de la

PHP SolutionsN" 5/2006 www.phpsolmag.org