PHP Extension W riting
Marcus Börger Johannes Schlüter
PHP Quebec 2009
PHP Extension W riting Marcus Brger Johannes Schlter PHP Quebec - - PowerPoint PPT Presentation
PHP Extension W riting Marcus Brger Johannes Schlter PHP Quebec 2009 Creating PHP 5 Extension PHP Lifecycle Adding objects Adding iterators to objects Brger, Schlter PHP Extension Writing 2 How the slides work
PHP Quebec 2009
PHP Extension Writing 2 Börger, Schlüter
PHP Extension Writing 3 Börger, Schlüter
Te xt i n ye l l ow Te xt you s houl d us e a s pr e s e nt e d Te x t i n gr e e n Te xt t ha t you ha ve t o r e pl a c e y our e x t Ext e ns i on na m e i n l owe r c a s e YOUREXT Ext e ns i on na m e i n uppe r c a s e Your Ex t Ext e ns i on na m e i n m i xe d c a s e ( c a m e l Ca ps )
Some special explanation use red text boxes
PHP Extension Writing 4 Börger, Schlüter
PHP Extension Writing 5 Börger, Schlüter
typedef struct _zval_struct { zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval;
typedef union _zvalue_value { long lval; double dval; struct { char *val; int len; } str; HashTable *ht; zend_object_value obj; } zvalue_value; IS_NULL IS_LONG IS_DOUBLE IS_BOOL IS_ARRAY IS_OBJECT IS_STRING IS_RESOURCE
PHP Extension Writing 6 Börger, Schlüter
typedef struct _zval_struct { zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval;
Userspace notion of "Reference" 0 == Not a reference 1 == Is a reference How many "labels" are associated with this zval?
PHP Extension Writing 7 Börger, Schlüter
typedef struct _zval_struct { zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval;
change, it must leave other labels with the original value. $a = 123; $b = $a; $b = 456; value.lval = 123 refcount = 2 type = IS_LONG is_ref = 0 $a $b
PHP Extension Writing 8 Börger, Schlüter
typedef struct _zval_struct { zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval;
change, it must leave other labels with the original value. $a = 123; $b = $a; $b = 456; value.lval = 123 refcount = 1 type = IS_LONG is_ref = 0 $a value.lval = 456 refcount = 1 type = IS_LONG is_ref = 0 $b
PHP Extension Writing 9 Börger, Schlüter
typedef struct _zval_struct { zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval;
change, it does so, causing other labels to see the new value. $a = 123; $b = &$a; $b = 456; value.lval = 123 refcount = 2 type = IS_LONG is_ref = 1 $a $b
PHP Extension Writing 10 Börger, Schlüter
typedef struct _zval_struct { zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval;
change, it does so, causing other labels to see the new value. $a = 123; $b = &$a; $b = 456; value.lval = 456 refcount = 2 type = IS_LONG is_ref = 1 $a $b
PHP Extension Writing 11 Börger, Schlüter
m a r c us @ z a phod s r c / php5/ ext $ . / e xt _s ke l - - ext na m e =ut i l Cr e a t i ng di r e ct or y ut i l Cr e a t i ng ba s i c f i l e s : c onf i g. m 4 . c vs i gnor e ut i l . c php_ut i l . h CREDI TS EXPERI M ENTAL t e s t s / 001. phpt ut i l . php [ done ] . To us e your new e xt e ns i on, you wi l l ha ve t o e xe c ut e t he f ol l owi ng s t e ps :
4
a ke
a ke Re pe a t s t e ps 3- 6 unt i l you a r e s a t i s f i e d wi t h e xt / ut i l / c onf i g. m 4 a nd s t e p 6 c onf i r m s t ha t your m
pi l ed i nt o PHP. Then, s t a r t wr i t i ng c ode and r e pe a t t he l a s t t wo s t e ps a s of t e n as ne ce s s a r y.
Necessary for non cvs source (e.g. release packages)
PHP Extension Writing 12 Börger, Schlüter
The header needed by php
The main extension code ('php_' prefix for .c is not necessary)
Used under * nix
Used under windows
List of files to be ignored by CVS
First line ext name 2nd line all authors
If available the API is not yet stable
Required for PECL extensions
Probably good to provide some lines
PHP Extension Writing 13 Börger, Schlüter
dnl $I d: $ dnl c onf i g. m 4 f or e xt e ns i on YOUREXT PHP_ARG_ENABLE( y our e x t , e na bl e Your Ex t s upppor t , [ - - e na bl e - y our e x t Ena bl e Your Ex t ] , no) i f t e s t " $PHP_YOUREXT" ! = " no" ; t he n AC_DEFI NE( HAVE_YOUREXT, 1, [ W he t he r Your Ex t i s pr e s e nt ] ) PHP_NEW _EXTENSI ON( y our e x t , php_y our e x t . c , $e xt _s ha r e d) f i
PHP Extension Writing 14 Börger, Schlüter
dnl $I d: $ dnl c onf i g. m 4 f or e xt e ns i on YOUREXT PHP_ARG_ENABLE( y our e x t , e na bl e Your Ex t s upppor t , [ - - e na bl e - y our e x t Ena bl e Your Ex t ] , no) i f t e s t " $PHP_YOUREXT" ! = " no" ; t he n i f t e s t " $e xt _s ha r e d" = " ye s " ; t he n AC_M SG_ERROR( Ca nnot bui l d YOUREXT a s a s ha r e d m
f i AC_DEFI NE( HAVE_YOUREXT, 1, [ W he t he r Your Ex t i s pr e s e nt ] ) PHP_NEW _EXTENSI ON( y our e x t , php_y our e x t . c , $e xt _s ha r e d) f i
PHP Extension Writing 15 Börger, Schlüter
/ / $I d: $ / / vi m : f t =j a va s c r i pt ARG_ENABLE( " y our e x t " , " Your Ex t s uppor t " , " ye s " ) ; i f ( PHP_YOUREXT == " ye s " ) { i f ( PHP_YOUREXT_SHARED) { ERROR( " YOUREXT c a nnot be c om pi l e d a s a s ha r e d e xt " ) ; } AC_DEFI NE( " HAVE_YOUREXT" , 1, " Your Ex t s uppor t " ) ; EXTENSI ON( " y our e x t " , " php_y our e x t . c " ) ; }
PHP Extension Writing 16 Börger, Schlüter
/ * Li c e ns e , Aut hor , CVS- Tag, Et c . . . */ #i f nde f PHP_YOUREXT_H #de f i ne PHP_YOUREXT_H #i nc l ude " php. h" e xt e r n z e nd_m
#de f i ne phpe xt _y our e x t _pt r & your e x t _m
/ * Onl y ne e de d i f you' l l be expor t i ng s ym bol s */ #i f de f PHP_W I N32 # de f i ne YOUREXT_API __de c l s pe c ( dl l e xpor t ) #e l s e # de f i ne YOUREXT_API #e ndi f / * Pl ac e f or gl obal s de f i ni t i on */ #e ndi f / * PHP_YOUREXT_H */
PHP Extension Writing 17 Börger, Schlüter
PHP Extension Writing 18 Börger, Schlüter
#i f de f HAVE_CONFI G_H #i nc l ude " c onf i g. h" #e ndi f #i nc l ude " php. h" #i nc l ude " php_i ni . h" #i nc l ude " e xt / s t a nda r d/ i nf o. h" #i nc l ude " e xt / s t a nda r d/ php_s t r i ng. h" #i nc l ude " php_y our e x t . h"
PHP Extension Writing 19 Börger, Schlüter
t ype de f s t r uc t _php_your e xt _da t a { i nt t ype ; c ha r *na m e ; i nt na m e _l e n; php_s t r e a m *s t r e a m ; } php_your e xt _da t a ; #de f i ne PHP_YOUREXT_M EANI NG 42 #de f i ne PHP_YOUREXT_COLOR " pur pl e " #de f i ne PHP_YOUREXT_STRLEN( v) ( v ? s t r l e n( v) : 0)
PHP Extension Writing 20 Börger, Schlüter
When dealing with PHP Data Use --enable-maintainer-zts when building PHP
If you need the funtion only in your .c file
If you plan to use the functions in other extensions
PHP Extension Writing 21 Börger, Schlüter s t a t i c voi d m y_he l pe r ( TSRM LS_D) ; s t a t i c voi d s om e _f unc t i on( TSRM LS_D) { m y_he l pe r ( TSRM LS_C) ; }
When dealing with PHP Data TSRMLS_D in declarations as only param TSRMLS_C in uses (calls) as only param
PHP Extension Writing 22 Börger, Schlüter s t a t i c voi d m y_he l pe r ( voi d * p TSRM LS_DC) ; s t a t i c voi d s om e _f unc t i on( voi d * p TSRM LS_DC) { m y_he l pe r ( p TSRM LS_CC) ; }
When dealing with PHP Data TSRMLS_D in declarations as only param TSRMLS_DC in declarations after last param w/ o comma TSRMLS_C in uses (calls) as only param TSRMLS_CC in uses after last param w/ o comma
PHP Extension Writing 23 Börger, Schlüter s t a t i c voi d m y_he l pe r ( c ha r *p, i nt p_l e n TSRM LS_DC) ; s t a t i c voi d s om e _f unc t i on( c har *p) { i nt p_l e n; TSRM LS_FETCH( ) ; p_l e n = s t r l e n( p) ; m y_he l pe r ( p, p_l e n TSRM LS_CC) ; }
When dealing with PHP Data TSRMLS_D in declarations as only param TSRMLS_DC in declarations after last param w/ o comma TSRMLS_C in implementations as only param TSRMLS_CC in impl. after last param w/ o comma TSRMLS_FETCH create a TSRM key, must follow last local var
PHP Extension Writing 24 Börger, Schlüter
z e nd_m
STANDARD_M ODULE_HEADER, " Your Ex t " , y our e x t _f unc t i ons , PHP_M I NI T( y our e x t ) , PHP_M SHUTDOW N( y our e x t ) , PHP_RI NI T( y our e x t ) , PHP_RSHUTDOW N( y our e x t ) , PHP_M I NFO( y our e x t ) , " 0. 1" , STANDARD_M ODULE_PROPERTI ES }; / * }}} */ #i f COM PI LE_DL_YOUREXT ZEND_GET_M ODULE( y our e x t ) #e ndi f
PHP Extension Writing 25 Börger, Schlüter
z e nd_f unc t i on_e nt r y y our e x t _f unc t i ons [ ] = { / * {{{ */ PHP_FE( y our e x t _f unc 1, y our e x t _ar gs _f unc 1) PHP_FE( y our e x t _f unc 2, NULL) PHP_FALI AS( y our e x t _f unc 3, y our e x t _f unc 2, NULL) PHP_NAM ED_FE( y our e x t _f unc 4, _y our e x t _f unc 4_i mpl , NULL) {NULL, NULL, NULL} };
PHP Extension Writing 26 Börger, Schlüter
s t a t i c ZEND_BEGI N_ARG_I NFO_EX( y our e x t _ar gs _f unc 1, 0, 0, 2) ZEND_ARG_I NFO( 0, par am_name 1) ZEND_ARG_ARRAY_I NFO( 1, par am_name 2) ZEND_END_ARG_I NFO( ) ;
name, pass_rest_by_ref, return_ref, required_args
pass_by_ref, name
pass_by_ref
pass_by_ref, name
pass_by_ref, name, classname, allow_null
PHP Extension Writing 27 Börger, Schlüter
/ * {{{ pr ot o t y pe y our e x t _name ( par ams ) Shor t de s c r i pt i on */ PHP_FUNCTI ON( y our e x t _name ) { / * Loc al de c l ar at i ons */ / * Par ame t e r par s i ng */ / * Ac t ual c ode */ / * Re t ur n v al ue */ } / * }}} */
Avoid / / style C+ + com ments Avoid declarations inline with code
PHP Extension Writing 28 Börger, Schlüter
/ * {{{ pr ot o nul l y our e x t _he l l o_wor l d( ) Sa y He l l o */ PHP_FUNCTI ON( y our e x t _he l l o_wor l d) { c ha r *gr e e t i ng = " He l l o W
php_pr i nt f ( " % s ! \ n" , gr e e t i ng) ; PHPW RI TE( gr e e t i ng, s t r l e n( gr e e t i ng) ) ; php_pr i nt f ( " ! \ n" ) ; } / * }}} */
PHP Extension Writing 29 Börger, Schlüter
i nt z e nd_pa r s e _pa r a m e t e r s ( i nt num _a r gs TSRM LS_DC, c ha r *t ype _s pe c , . . . ) ; i nt z e nd_pa r s e _pa r a m e t e r s _e x( i nt f l a gs , i nt num _a r gs TSRM LS_DC, c ha r *t ype _s pe c , . . . ) ; f l a gs 0 or ZEND_PARSE_PARAM S_QUI ET num _a r gs us e ZEND_NUM _ARGS( ) t ype _s pe c s s c a nf l i ke t ype l i s t ( t hough no % ) . . . Re f e r e nc e s t o t he t ype s gi ve n i n t ype _s pe c r e t ur ns SUCCESS or FAI LURE i n c a s e of f a i l ur e a n e r r or i s a l r e a dy i s s ue d s o no ne e d f or ZEND_W RONG_PARAM _COUNT( ) unl e s s us i ng ZEND_PARSE_PARAM S_QUI ET
PHP Extension Writing 30 Börger, Schlüter
t ype _s pe c s s c a nf l i ke t ype l i s t ( t hough no % ) l l ong l ong * d doubl e doubl e * b bool e a n z e nd_bool * a a r r a y z va l **
z va l ** O
z va l **, z e nd_c l a s s _e nt r y * Obj e c t m us t be de r i ve d f r om gi ve n c l a s s s s t r i ng c ha r **, i nt * You r e c e i ve s t r i ng a nd l e ngt h r r e s our c e z va l ** z z va l z va l ** Z z va l - r e f z va l *** | r i ght pa r t i s opt i ona l / ne xt pa r a m ge t s s e pa r a t e d i f not r e f e r e nc e ! Ne xt pa r a m r e t ur ns NULL i f pa r a m t ype I S_NULL
PHP Extension Writing 31 Börger, Schlüter
/ * {{{ pr ot o nul l y our e x t _he l l o( s t r i ng na m e ) Gr e e t by na m e */ PHP_FUNCTI ON( y our e x t _he l l o) { c ha r *na m e ; i nt na m e _l e n; i f ( z e nd_pa r s e _pa r a m e t e r s ( ZEND_NUM _ARGS( ) TSRM LS_CC, " s " , & na m e , & na m e _l e n) == FAI LURE) { r e t ur n; } php_pr i nt f ( " He l l o % s ! \ n" , na m e ) ; } / * }}} */
PHP Extension Writing 32 Börger, Schlüter
/ * {{{ pr ot o bool y our e x t _he l l o( s t r i ng na m e ) Gr e e t by na m e */ PHP_FUNCTI ON( y our e x t _he l l o) { c ha r *na m e ; i nt na m e _l e n; i f ( z e nd_pa r s e _pa r a m e t e r s ( ZEND_NUM _ARGS( ) TSRM LS_CC, " s " , & na m e , & na m e _l e n) == FAI LURE) { r e t ur n; } php_pr i nt f ( " He l l o % s ! \ n" , na m e ) ; RETURN_TRUE; } / * }}} */ Makes the return value NULL
PHP Extension Writing 33 Börger, Schlüter
RETURN_NULL( ) ; RETURN_BOOL( b) ; b: 0 => FALSE, non- 0 => TRUE RETURN_TRUE; RETURN_BOOL( 1) RETURN_FALSE; RETURN_BOOL( 0) RETURN_LONG( l ) ; l : I nt e ge r va l ue RETURN_DOUBLE( d) ; d: Fl oa t i ng poi nt va l ue
PHP Extension Writing 34 Börger, Schlüter
RETURN_STRI NG( s t r , dup) s t r : c har * s t r i ng va l ue dup: 0/ 1 f l ag, dupl i c at e s t r i ng? RETURN_STRI NGL( s t r , l en, dup) l e n: Pr ede t er m i ne d s t r i ng l engt h RETURN_STRI NG( " He l l o W
RETURN_STRI NG( es t r dup( " He l l o W
RETURN_EM PTY_STRI NG( ) ;
PHP Extension Writing 35 Börger, Schlüter
#de f i ne RETURN_NULL( ) { RETVAL_NULL( ) ; r e t ur n; } #de f i ne RETURN_TRUE { RETVAL_TRUE; r e t ur n; } #de f i ne RETURN_FALSE { RETVAL_FALSE; r e t ur n; } #de f i ne RETURN_BOOL( b) { RETVAL_BOOL( b) ; r e t ur n; } #de f i ne RETURN_LONG( l ) { RETVAL_LONG( l ) ; r e t ur n; } #de f i ne RETURN_DOUBLE( d) { RETVAL_DOUBLE( d) ; r e t ur n; } #de f i ne RETURN_STRI NG( s t r , dup) \ { RETVAL_STRI NG( s t r , dup) ; r e t ur n; } #de f i ne RETURN_STRI NGL( s t r , l e n, dup) \ { RETVAL_STRI NGL( s t r , l e n, dup) ; r e t ur n; } #de f i ne RETURN_EM PTY_STRI NG( ) \ { RETVAL_EM PTY_STRI NG( ) ; r e t ur n; }
PHP Extension Writing 36 Börger, Schlüter
#de f i ne RETVAL_NULL( ) ZVAL_NULL( r et ur n_va l ue) #de f i ne RETVAL_TRUE ZVAL_TRUE( r et ur n_va l ue) #de f i ne RETVAL_FALSE ZVAL_FALSE( r e t ur n_va l ue) #de f i ne RETVAL_BOOL( b) ZVAL_BOOL( r et ur n_va l ue, b) #de f i ne RETVAL_LONG( l ) ZVAL_LONG( r et ur n_va l ue, l ) #de f i ne RETVAL_DOUBLE( d) ZVAL_DOUBLE( r e t ur n_va l ue , d) #de f i ne RETVAL_STRI NG( s t r , dup) \ ZVAL_STRI NG( r e t ur n_va l ue , s t r , dup) #de f i ne RETVAL_STRI NGL( s t r , l e n, dup) \ ZVAL_STRI NGL( r et ur n_val ue , s t r , l e n, dup) #de f i ne RETVAL_EM PTY_STRI NG( ) \ ZVAL_EM PTY_STRI NG( r e t ur n_va l ue )
PHP Extension Writing 37 Börger, Schlüter
#de f i ne RETVAL_NULL( ) ZVAL_NULL( r et ur n_va l ue) #de f i ne RETVAL_TRUE ZVAL_TRUE( r et ur n_va l ue) #de f i ne RETVAL_FALSE ZVAL_FALSE( r e t ur n_va l ue) #de f i ne RETVAL_BOOL( b) ZVAL_BOOL( r et ur n_va l ue, b) #de f i ne RETVAL_LONG( l ) ZVAL_LONG( r et ur n_va l ue, l ) #de f i ne RETVAL_DOUBLE( d) ZVAL_DOUBLE( r e t ur n_va l ue , d) #de f i ne RETVAL_STRI NG( s t r , dup) \ ZVAL_STRI NG( r e t ur n_va l ue , s t r , dup) #de f i ne RETVAL_STRI NGL( s t r , l e n, dup) \ ZVAL_STRI NGL( r et ur n_val ue , s t r , l e n, dup) #de f i ne RETVAL_EM PTY_STRI NG( ) \ ZVAL_EM PTY_STRI NG( r e t ur n_va l ue )
PHP Extension Writing 38 Börger, Schlüter
/ * {{{ pr ot o bool y our e x t _i nve r t ( bool b) I nve r t a bool e a n pa r a m e t e r */ PHP_FUNCTI ON( y our e x t _i nve r t ) { z e nd_bool b; i f ( z e nd_pa r s e _pa r a m e t e r s ( ZEND_NUM _ARGS( ) TSRM LS_CC, " b" , & b) == FAI LURE) { r e t ur n; } b = b ? 0 : 1; RETURN_BOOL( b) ; } / * }}} */
PHP Extension Writing 39 Börger, Schlüter
/ * {{{ pr ot o i nt y our e x t _i nc r e m e nt ( i nt v [ , i nt m a x] ) I nc r e m e nt a va l ue wi t h opt i ona l m a xi m um */ PHP_FUNCTI ON( y our e x t _i nc r e m e nt ) { l ong n, nm a x = LONG_M AX; i f ( z e nd_pa r s e _pa r a m e t e r s ( ZEND_NUM _ARGS( ) TSRM LS_CC, " l | l " , & n, & nm a x) == FAI LURE) { RETURN_FALSE( ) ; } n = ( n+1) % nm a x; RETURN_LONG( n) ; } / * }}} */ Initialize
values Use brackets for optional values A vertical bar separates
parameters
PHP Extension Writing 40 Börger, Schlüter
#de f i ne YOUREXT_VERSI ON_M AJ OR #de f i ne YOUREXT_VERSI ON_M I NOR 1 / * {{{ pr ot o s t r i ng y our e x t _ve r s i on( ) Re t r i e ve y our e x t ve r s i on */ PHP_FUNCTI ON( y our e x t _ve r s i on) { c ha r * ve r ; i nt l e n; l e n = s ppr i nt f ( & ve r , 0, " %
d ( % s ) " , YOUREXT_VERSI ON_M AJ OR, YOUREXT_VERSI ON_M I NOR, " $I d: $" ) ; RETURN_STRI NGL( ve r , l e n, 0) ; } / * }}} */
Never use sprintf, use either snprintf or spprintf No need to copy the string
PHP Extension Writing 41 Börger, Schlüter
i nt a dd_a s s oc _l ong( z va l *a r g, c ha r *ke y, l ong n) ; i nt a dd_a s s oc _nul l ( z va l *a r g, c ha r *ke y) ; i nt a dd_a s s oc _bool ( z va l *a r g, c ha r *ke y, i nt b) ; i nt a dd_a s s oc _r e s our c e ( z va l *a r g, c ha r *ke y, i nt r ) ; i nt a dd_a s s oc _doubl e ( z va l *a r g, c ha r *ke y, doubl e d) ; i nt a dd_a s s oc _s t r i ng( z va l *a r g, c ha r *ke y, c ha r *s t r , i nt dup) ; i nt a dd_a s s oc _s t r i ngl ( z va l *a r g, c ha r *ke y, c ha r *s t r , ui nt l e n, i nt dup) ; i nt a dd_a s s oc _z va l ( z va l *a r g, c ha r *ke y, z va l *va l ue ) ;
PHP Extension Writing 42 Börger, Schlüter
i nt a dd_i nde x_l ong( z va l *a r g, ui nt i dx, l ong n) ; i nt a dd_i nde x_nul l ( z va l *a r g, ui nt i dx) ; i nt a dd_i nde x_bool ( z va l *a r g, ui nt i dx, i nt b) ; i nt a dd_i nde x_r e s our c e ( z va l *a r g, ui nt i dx, i nt r ) ; i nt a dd_i nde x_doubl e ( z va l *a r g, ui nt i dx, doubl e d) ; i nt a dd_i nde x_s t r i ng( z va l *a r g, ui nt i dx, c ha r *s t r , i nt dupl i c a t e ) ; i nt a dd_i nde x_s t r i ngl ( z va l *a r g, ui nt i dx, c ha r *s t r , ui nt l e ngt h, i nt dupl i c a t e ) ; i nt a dd_i nde x_z va l ( z va l *a r g, ui nt i dx, z va l *va l ue ) ;
PHP Extension Writing 43 Börger, Schlüter
i nt a dd_ne xt _i nde x_l ong( z va l *a r g, l ong n) ; i nt a dd_ne xt _i nde x_nul l ( z va l *a r g) ; i nt a dd_ne xt _i nde x_bool ( z va l *a r g, i nt b) ; i nt a dd_ne xt _i nde x_r e s our c e ( z va l *a r g, i nt r ) ; i nt a dd_ne xt _i nde x_doubl e ( z va l *a r g, doubl e d) ; i nt a dd_ne xt _i nde x_s t r i ng( z va l *a r g, c ha r *s t r , i nt dupl i c a t e ) ; i nt a dd_ne xt _i nde x_s t r i ngl ( z va l *a r g, c ha r *s t r , ui nt l e ngt h, i nt dupl i c a t e ) ; i nt a dd_ne xt _i nde x_z va l ( z va l *a r g, z va l *va l ue ) ;
PHP Extension Writing 44 Börger, Schlüter
/ * {{{ pr ot o a r r a y y our e x t _ve r s i on_a r r a y( ) Re t r i e ve y our e x t ve r s i on a s a r r a y */ PHP_FUNCTI ON( y our e x t _ve r s i on_a r r a y) { c ha r *ve r ; i nt l e n = s ppr i nt f ( & ve r , 0, " %
d" , YOUREXT_VERSI ON_M AJ OR, YOUREXT_VERSI ON_M I NOR) ; a r r a y_i ni t ( r e t ur n_va l ue ) ; a dd_a s s oc _l ong( r e t ur n_va l ue , " m a j or " , YOUREXT_VERSI ON_M AJ OR) ; a dd_a s s oc _l ong( r e t ur n_va l ue , " m i nor " , YOUREXT_VERI SON_M I NOR) ; a dd_a s s oc _s t r i ng( r e t ur n_va l ue , " c vs " , " $I d: $" , 1) ; a dd_a s s oc _s t r i ngl ( r e t ur n_va l ue , " ve r " , ve r , l e n, 0) ; } / * }}} */
make return_value an array
PHP Extension Writing 45 Börger, Schlüter
/ * a r Ke y ha s he d us i ng DJ BX33A */ ul ong z e nd_ge t _ha s h_va l ue ( c ha r *a r Ke y, ui nt nKe yLe ngt h) ; / * c ount ( $ht ) */ i nt z e nd_ha s h_num _e l e m e nt s ( Ha s hTa bl e *ht ) ; / * Re m
e nt s f r om t he Ha s hTa bl e */ i nt z e nd_ha s h_c l e a n( Ha s hTa bl e *ht ) ;
PHP Extension Writing 46 Börger, Schlüter
a dd_a s s oc _z va l ( a r r , " f oo" , va l ) ; a dd_a s s oc _z va l _e x( a r r , " f oo" , s i z e of ( " f oo" ) , va l ) ; z e nd_s ym t a bl e _upda t e ( Z_ARRVAL_P( a r r ) , " f oo" , s i z e of ( " f oo" ) , & va l , s i z e of ( z va l *) , NULL) ;
sizeof(key) vs. strlen(key)
PHP Extension Writing 47 Börger, Schlüter
i nt z e nd_ha s h_de l ( Ha s hTa bl e *ht , c ha r *a r Ke y, ui nt nKe yLe n) ; i nt z e nd_ha s h_i nde x_de l ( Ha s hTa bl e *ht , ul ong h) ; i nt z e nd_s ym t a bl e _de l ( Ha s hTa bl e *ht , c ha r *a r Ke y, ui nt nKe yLe ngt h) ;
PHP Extension Writing 48 Börger, Schlüter
i nt z e nd_ha s h_e xi s t s ( Ha s hTa bl e *ht , c ha r *a r Ke y, ui nt nKe yLe ngt h) ; i nt z e nd_ha s h_qui c k_e xi s t s ( Ha s hTa bl e *ht , c ha r *a r Ke y, ui nt nKe yLe ngt h, ul ong h) ; i nt z e nd_ha s h_i nde x_e xi s t s ( Ha s hTa bl e *ht , ul ong h) ; i nt z e nd_s ym t a bl e _e xi s t s ( Ha s hTa bl e *ht , c ha r *a r Ke y, ui nt nKe yLe ngt h) ;
PHP Extension Writing 49 Börger, Schlüter
i nt z e nd_ha s h_f i nd( Ha s hTa bl e *ht , c ha r *a r Ke y, ui nt nKe yLe ngt h, voi d **pDa t a ) ; i nt z e nd_ha s h_qui c k_f i nd( Ha s hTa bl e *ht , c ha r *a r Ke y, ui nt nKe yLe ngt h, ul ong h, voi d **pDa t a ) ; i nt z e nd_ha s h_i nde x_f i nd( Ha s hTa bl e *ht , ul ong h, voi d **pDa t a ) ; i nt z e nd_s ym t a bl e _f i nd( Ha s hTa bl e *ht , c ha r *a r Ke y, ui nt nKe yLe ngt h, voi d **pDa t a ) ;
PHP Extension Writing 50 Börger, Schlüter
z va l **t m p; i f ( z e nd_s ym t a bl e _f i nd( ht , " ke y" , s i z e of ( " ke y" ) , ( voi d**) & t m p) == SUCCESS) { / * Do s om e t hi ng wi t h t m p */ i f ( Z_TYPE_PP( t m p) == I S_STRI NG) { PHPW RI TE( Z_STRVAL_PP( t m p) , Z_STRLEN_PP( t m p) ) ; } }
PHP Extension Writing 51 Börger, Schlüter
Z_LVAL( zva l ) l ong va l ue Z_BVAL( zva l ) z e nd_bool va l ue Z_DVAL( zva l ) doubl e va l ue Z_STRVAL( z val ) c ha r * va l ue Z_STRLEN( z val ) i nt l e ngt h Z_ARRVAL( z val ) Ha s hTa bl e *
Z_OBJ _HANDLE( z va l ) i nt
Z_OBJ _HT( z val ) z e nd_obj e c t _ha ndl er s *
Z_OBJ CE( z va l ) z e nd_c l as s _ent r y*
Z_OBJ PROP( z va l ) Ha s hTa bl e * pr oper t i e s Z_OBJ _HANDLER( zva l , hf ) Z_OBJ _HT( ( z va l ) ) - >hf
Z_RESVAL( z val ) i nt r e s our c e i d Z_TYPE( zva l ) i nt I S_* HASH_OF( z va l ) Ha s hTa bl e * a r r a y+pr ops Z_*_P( z p) Z_*( *z p) Z_*_PP( zpp) Z_*( **z pp)
PHP Extension Writing 52 Börger, Schlüter
Z_REFCOUNT( zva l ) Re t r i e ve r e f e r enc e c ount Z_SET_REFCOUNT( z val , r c) Se t r e f er e nce count t o <r c > Z_ADDREF( z val ) I nc r em e nt r ef e r e nce c ount Z_DELREF( z val ) De c r em e nt r ef e r e nce c ount Z_I SREF( z va l ) W he t he r z va l i s a r e f er e nc e Z_SET_I SREF( z val ) M a ke s z va l a r ef e r e nc e va r i abl e Z_UNSET_I SREF( zva l ) Re s e t s t he i s - r e f er e nce f l a g Z_SET_I SREF_TO( z val , i s ) M a ke z val a r e f e r enc e i s <i s > ! = 0 Z_*_P( z p) Z_*( *z p) Z_*_PP( zpp) Z_*( **z pp)
PHP Extension Writing 53 Börger, Schlüter
ZVAL_NULL( z p) I S_NULL J us t s e t t he t ype ZVAL_RESOURCE( zp, l ) I S_RESOURCE Se t t o r e s our c e <l > ZVAL_BOOL( z p, b) I S_BOOL Se t t o bool ea n <b> ZVAL_FALSE( zp) I S_BOOL Se t t o f a l s e ZVAL_TRUE( z p) I S_BOOL Se t t o t r ue ZVAL_LONG( z p, l ) I S_LONG Se t t o l ong <l > ZVAL_DOUBLE( z p, d) I S_DOUBLE Se t t o doubl e <d> ZVAL_STRI NG( z p, s , dup) I S_STRI NG Se t s t r i ng ZVAL_STRI NGL( z p, s , l , dup) I S_STRI NG Se t s t r i ng and l e ngt h ZVAL_EM PTY_STRI NG( z p) I S_STRI NG Se t as em pt y s t r i ng ZVAL_ZVAL( z p, z v, c opy, dt or ) Copy t he z val and i t s t ype . Al l ows t o c al l c opyi ng, ne c es s ar y f or s t r i ngs e t c . Al l ows t o des t r uc t ( del r e f ) t he or i gi na l z va l .
PHP Extension Writing 54 Börger, Schlüter
ALLOC_ZVAL( zp) Al l oca t e a zva l us i ng em a l l oc ( ) I NI T_PZVAL( zp) Se t r e f er e nce count a nd i s r ef 0 I NI T_ZVAL( z va l ) I ni t i a l i z e and s e t NULL, no poi nt e r ALLOC_I NI T_ZVAL( z p) Al l oca t e a nd i ni t i a l i ze a z va l M AKE_STD_ZVAL( zp) Al l oca t e, i ni t i a l i z e and s e t NULL Exa m pl e : z va l *val ; ALLOC_I NI T_ZVAL( val ) ; ZVAL_STRI NGL( val , “ M yval ” , s i z eof ( “m yva l ”) - 1, 1)
PHP Extension Writing 55 Börger, Schlüter
/ * a r r a y_wa l k( $ht , $a ppl y_f unc ) */ voi d z e nd_has h_a ppl y( Has hTa bl e *ht , a ppl y_f unc _t a ppl y_f unc TSRM LS_DC) ; / * a r r a y_wa l k( $ht , $a ppl y_f unc , $dat a ) */ voi d z e nd_has h_a ppl y_wi t h_a r gum e nt ( Ha s hTabl e *ht , a ppl y_f unc _ar g_t appl y_f unc , voi d * TSRM LS_DC) ; / * M ul t i pl e a r gum ent ver s i on, * Thi s i s al s o t he onl y va r i a nt whi c h pr ovi des * t he ke y t o t he c a l l ba c k */ voi d z e nd_has h_a ppl y_wi t h_a r gum e nt s ( Has hTa bl e *ht , a ppl y_f unc _ar gs _t a ppl y_f unc, i nt , . . . ) ;
PHP Extension Writing 56 Börger, Schlüter
/ * pDe s t c ont a i ns a poi nt e r t o * wha t ' s s t or ed i n t he Ha s hTa bl e * Si nc e t her e i s a z val * i n Sym bol Ta bl e s * we wi nd up wi t h a zva l ** be i ng pa s s e d a s pDe s t * t ype de f i nt ( *appl y_f unc _t ) ( voi d *pDe s t TSRM LS_DC) ; t ype de f i nt ( *appl y_f unc _a r g_t ) ( voi d *pDes t , voi d *a r gum ent TSRM LS_DC) ; t ype de f i nt ( *appl y_f unc _a r gs _t ) ( voi d *pDe s t , i nt num _a r gs , va _l i s t a r gs , z e nd_ha s h_key *ha s h_key) ;
PHP Extension Writing 57 Börger, Schlüter
/ * Cont i nue i t t e r at i ng t he Ha s hTa bl e */ #de f i ne ZEND_HASH_APPLY_KEEP / * Rem
e nt , but c ont i nue pr oce s s i ng */ #de f i ne ZEND_HASH_APPLY_REM OVE 1<<0 / * Ter m i na t e t he l oop ( br e a k; ) */ #de f i ne ZEND_HASH_APPLY_STOP 1<<1
PHP Extension Writing 58 Börger, Schlüter
/ * {{{ pr ot o voi d y our ex t _f or e ac h( a r r a y nam e s , s t r i ng gr e e t i ng) Sa y he l l o t o e ac h pe r s on */ PHP_FUNCTI ON( y our ex t _f or e a c h) { z va l *nam e s ; c ha r *gr e e t ; i nt gr e et _l en; i f ( ze nd_pa r s e _pa r a m e t er s ( ZEND_NUM _ARGS( ) TSRM LS_CC, " a s " , & na m e s , & gr ee t , & gr e e t _l en) == FAI LURE) { r e t ur n; } z e nd_ha s h_a ppl y_wi t h_ar gum e nt ( Z_ARRVAL_P( na m es ) , ( a ppl y_f unc _a r g_t ) y our ex t _f or e ac h, gr ee t TSRM LS_CC) ; } / * }}} */
PHP Extension Writing 59 Börger, Schlüter
/ * {{{ your ex t _f or e a c h Ca l l bac k f or out put t i ng a gr ee t i ng f or e ac h na m e i n a us e r - pr ovi de d a r r a y */ i nt your e x t _f or e a ch( z val **pa r am , cha r *gr e e t i ng TSRM LS_DC) { i f ( Z_TYPE_PP( pa r am ) == I S_STRI NG) { php_pr i nt f ( " % s % s \ n" , gr e e t i ng, Z_STRVAL_PP( par a m ) ) ; r e t ur n ZEND_HASH_APPLY_KEEP; } e l s e { php_er r or _doc r ef ( NULL TSRM LS_CC, E_W ARNI NG, " Non- s t r i ng va l ue pa s s ed i n $nam e s a r r a y" ) ; r e t ur n ZEND_HASH_APPLY_STOP; } } / * }}} */
PHP Extension Writing 60 Börger, Schlüter
PHP Extension Writing 61 Börger, Schlüter
(loaded by php.ini)
PHP Extension Writing 62 Börger, Schlüter
PHP Extension Writing 63 Börger, Schlüter
PHP Extension Writing 64 Börger, Schlüter
(in reverse of activation order)
PHP Extension Writing 65 Börger, Schlüter
(rev. startup order)
MINIT RUNTIME RINIT RSHUTDOWN MSHUTDOWN RUNTIME RINIT RSHUTDOWN
Request 1 Request n
PHP Extension Writing 66 Börger, Schlüter
voi d * m a l l oc ( s i ze _t s i z e ) ; voi d * c a l l oc ( s i ze _t nm e m b, s i z e _t s i z e ) ; voi d * r e a l l oc( voi d *pt r , s i z e_t s i z e) ; voi d * s t r dup( c har *s t r ) ; voi d * s t r ndup( c ha r *s t r , s i z e_t l e n) ; voi d f r e e ( voi d *pt r ) ;
PHP Extension Writing 67 Börger, Schlüter
voi d * em a l l oc ( s i ze _t s i z e ) ; voi d * ec a l l oc ( s i ze _t nm e m b, s i z e _t s i z e ) ; voi d * er e a l l oc( voi d *pt r , s i z e_t s i z e) ; voi d * es t r dup( c har *s t r ) ; voi d * es t r ndup( c ha r *s t r , s i z e_t l e n) ; voi d e f r e e ( voi d *pt r ) ; voi d *s af e _em a l l oc( s i ze_t nm e m b, s i z e _t s i z e , s i z e _t adt l ) ; void *STR_EMPTY_ALLOC(void);
PHP Extension Writing 68 Börger, Schlüter
voi d *pem a l l oc ( s i ze _t s i z e , i nt pe r s i s t ) ; voi d *pec a l l oc ( s i ze _t nm e m b, s i z e _t s i z e , i nt pe r s i s t ) ; voi d *per e a l l oc( voi d *pt r , s i z e_t s i z e, i nt per s i s t ) ; voi d *pes t r dup( c har *s t r , i nt pe r s i s t ) ; voi d pe f r e e ( voi d *pt r , i nt pe r s i s t ) ; voi d *s af e _pe m al l oc ( s i ze _t nm e m b, s i z e_t s i z e, s i z e _t addt l , i nt pe r s i s t ) ;
PHP Extension Writing 69 Börger, Schlüter
s t a t i c c ha r *e r r or m s g = NULL; PHP_FUNCTI ON( y our e x t _unt hr e a ds a f e ) { l ong r e t ; r e t = do_s om e t hi ng( " va l ue " , & e r r or m s g) ; i f ( e r r or m s g) { php_e r r or _doc r e f ( NULL TSRM LS_CC, E_W ARNI NG, " do_s om e t hi ng( ) f a i l e d wi t h: % s " , e r r or m s g) ; f r e e ( e r r or m s g) ; e r r or m s g = NULL; } }
PHP Extension Writing 70 Börger, Schlüter
ZEND_BEGI N_M ODULE_GLOBALS( y our e x t ) c ha r *s t r ; i nt s t r l e n; l ong c ount e r ; ZEND_END_M ODULE_GLOBALS( y our e x t ) #i f de f ZTS # de f i ne YOUREXT_G( v) \ TSRM G( y our e x t _gl oba l s _i d, z e nd_y our e x t _gl oba l s *, v) e xt e r n i nt y our e x t _gl oba l s _i d; #e l s e # de f i ne YOUREXT_G( v) ( y our e x t _gl oba l s . v) e xt e r n z e nd_y our e x t _gl oba l s y our e x t _gl oba l s ; #e ndi f
PHP Extension Writing 71 Börger, Schlüter
ZEND_DECLARE_M ODULE_GLOBALS( y our e x t ) s t a t i c voi d y our e xt _gl oba l s _c t or ( z e nd_y our e x t _gl obal s *gl oba l s ) { / * I ni t i al i z e your gl obal s t r uct */ gl obal s - >s t r = NULL; gl obal s - >s t r l e n = 0; gl obal s - >c ount er = 0; } s t a t i c voi d y our e xt _gl oba l s _dt or ( z e nd_y our e x t _gl obal s *gl oba l s ) { / * Cl e a n up a ny a l l oc at e d gl obal s */ }
PHP Extension Writing 72 Börger, Schlüter
PHP_M I NI T_FUNCTI ON( your e xt ) { ZEND_I NI T_M ODULE_GLOBALS( y our e xt , y our ex t _gl oba l s _c t or , your e xt _gl obal s _dt or ) ; r e t ur n SUCCESS; } PHP_M SHUTDOW N_FUNCTI ON( your ext ) { #i f nde f ZTS y our ex t _gl oba l s _dt or ( & your e xt _gl obal s TSRM LS_CC) ; #e ndi f r e t ur n SUCCESS; }
PHP Extension Writing 73 Börger, Schlüter
PHP_RI NI T_FUNCTI ON( your e xt ) { / * Tr a c k num be r of t i m es t hi s t hr e ad/ pr oce s s * has s e r vi c e d r eque s t s */ YOUREXT_G( c ount e r ) ++; r e t ur n SUCCESS; } PHP_RSHUTDOW N_FUNCTI ON( your ext ) { i f ( YOUREXT_G( s t r ) ) { e f r e e( YOUREXT_G( s t r ) ) ; YOUREXT_G( s t r ) = NULL; } r e t ur n SUCCESS; }
PHP Extension Writing 74 Börger, Schlüter
PHP_FUNCTI ON( y our ex t _s et _s t r i ng) { c ha r *s t r ; i nt s t r _l e n; i f ( ze nd_pa r s e _pa r a m e t er s ( ZEND_NUM _ARGS( ) , " s " , & s t r , & s t r _l e n) == FAI LURE) { r e t ur n; } i f ( YOUREXT_G( s t r ) ) { e f r e e( YOUREXT_G( s t r ) ) ; } YOUREXT_G( s t r ) = es t r ndup( s t r , s t r _l e n) ; YOUREXT_G( s t r l en) = s t r _l e n; RETURN_TRUE; }
PHP Extension Writing 75 Börger, Schlüter
PHP_FUNCTI ON( y our ex t _get _s t r i ng) { i f ( YOUREXT_G( s t r ) ) { RETURN_STRI NGL( YOUREXT_G( s t r ) , YOUREXT_G( s t r l e n) , 1) ; } e l s e { RETURN_EM PTY_STRI NG( ) ; } }
PHP Extension Writing 76 Börger, Schlüter
Do not use string variables!
i nt ze nd_ge t _c ons t a nt ( cha r *na m e , ui nt nam e _l en, z va l *r es ul t TSRM LS_DC) ; REGI STER_LONG_CONSTANT( na m e , l va l , f l ags ) REGI STER_DOUBLE_CONSTANT( na m e , dva l , f l a gs ) REGI STER_STRI NG_CONSTANT( na m e , s t r , f l a gs ) REGI STER_STRI NGL_CONSTANT( nam e , s t r , l e n, f l ags ) i nt ze nd_r e gi s t e r _c ons t a nt ( ze nd_c ons t ant *c TSRM LS_DC) ; / * Cas e - s e ns i t i ve */ #de f i ne CONST_CS ( 1<<0) / * Per s i s t e nt */ #de f i ne CONST_PERSI STENT ( 1<<1)
PHP Extension Writing 77 Börger, Schlüter
PHP_M I NI T_FUNCTI ON( y our e x t ) { REGI STER_LONG_CONSTANT( " YOUREXT_CONSTNAM E" , 42, CONST_CS | CONST_PERSI STENT) ; REGI STER_STRI NG_CONSTANT( " YOUREXT_VERSI ON" , " $I D: $" , CONST_CS | CONST_PERSI STENT) ; r e t ur n SUCCESS; } PHP_RI NI T_FUNCTI ON( y our e x t ) { REGI STER_LONG_CONSTANT( " YOUREXT_COUNTER" , YOUREXT_G( c ount e r ) , CONST_CS) ; r e t ur n SUCCESS; }
PHP Extension Writing 78 Börger, Schlüter
PHP_M I NFO_FUNCTI ON( y our e x t ) { php_i nf o_pr i nt _t a bl e _s t a r t ( ) ; php_i nf o_pr i nt _t a bl e _he a de r ( 2, " Your Ex t " , " e nabl e d" ) ; php_i nf o_pr i nt _t a bl e _r ow( 2, " Ve r s i on" , " $I D: $" ) ; php_i nf o_pr i nt _t a bl e _r ow( 2, " Some s t r i ng" , YOUREXT_G( s t r ) ) ; php_i nf o_pr i nt _t a bl e _e nd( ) ; }
PHP Extension Writing 79 Börger, Schlüter
PHP Extension Writing 80 Börger, Schlüter
PHP Extension Writing 81 Börger, Schlüter
PHP Extension Writing 82 Börger, Schlüter
zval ref_count is_ref handle handlers zend_object_store_get()
zend_object_handlers tables zvals zend_class_entry
PHP Extension Writing 83 Börger, Schlüter
zend_class_entry function_table iterator_funcs create_object() get_iterator() interface_gets_implemented() int (*serialize)(…) int (*unserialize)(…) // function caches zend_object_handlers zend_object_iterator PHP_METHOD
PHP Extension Writing 84 Börger, Schlüter z e nd_c l a s s _e nt r y *ut i l _ce _di r ; PHP_M I NI T_FUNCTI ON( ut i l ) / * {{{ */ { z e nd_c l a s s _e nt r y c e ; I NI T_CLASS_ENTRY( c e , " di r s " , ut i l _di r _c l a s s _f unc t i ons ) ; ut i l _c e _di r = z e nd_r e gi s t e r _i nt e r na l _c l a s s ( & c e TSRM LS_CC) ; ut i l _c e _di r - >cr e a t e _obj ec t = ut i l _di r _obj e ct _ne w; m e m c py( & ut i l _di r _ha ndl e r s , z end_ge t _s t d_obj e c t _ha ndl er s ( ) , s i z e of ( z e nd_obj e c t _ha ndl e r s ) ) ; ut i l _di r _ha ndl e r s . c l one _obj = ut i l _di r _obj ec t _c l one ; z e nd_c l a s s _i m pl e m e nt s ( ut i l _c e_di r TSRM LS_CC, 1, z e nd_c e _i t e r a t or ) ; ut i l _c e _di r - >ce _f l a gs | = ZEND_ACC_FI NAL_CLASS; ut i l _c e _di r - >ge t _i t e r a t or = ut i l _di r _ge t _i t e r a t or ; r e t ur n SUCCESS; } / * }}} */
PHP Extension Writing 85 Börger, Schlüter i nt z e nd_de c l ar e _c l a s s _cons t ant ( z e nd_c l a s s _e nt r y *c e , c ha r *na m e , s i z e _t na m e _l e n, z va l *va l ue TSRM LS_DC) ; i nt z e nd_de c l ar e _c l a s s _cons t ant _l ong( z e nd_cl a s s _e nt r y *c e , c ha r *na m e , s i z e _t na m e _l e n, l ong va l ue TSRM LS_DC) ; i nt z e nd_de c l ar e _c l a s s _cons t ant _bool ( z e nd_cl a s s _e nt r y *c e , c ha r *na m e , s i z e _t na m e _l e n, z e nd_bool va l ue TSRM LS_DC) ; i nt z e nd_de c l ar e _c l a s s _cons t ant _doubl e ( z e nd_c l a s s _e nt r y *ce , c ha r *na m e , s i z e _t na m e _l e n, doubl e va l ue TSRM LS_DC) ; i nt z e nd_de c l ar e _c l a s s _cons t ant _s t r i ngl ( z e nd_c l a s s _e nt r y *c e , c ha r *na m e , s i z e _t na m e _l e n, c ha r *va l , s i ze _t va l _l en TSRM LS_DC) ; i nt z e nd_de c l ar e _c l a s s _cons t ant _s t r i ng( z e nd_c l a s s _e nt r y *ce , c ha r *na m e , s i z e _t na m e _l e n, c ha r *va l ue TSRM LS_DC) ;
PHP Extension Writing 86 Börger, Schlüter / * de c l a r e m e t hod pa r a m et e r s , */ s t a t i c ZEND_BEGI N_ARG_I NFO( a r gi nf o_di r ___c ons t r uc t , 0) ZEND_ARG_I NFO( 0, pa t h) / * par a m e t e r na m e */ ZEND_END_ARG_I NFO( ) ; / * e a c h m e t hod c a n ha ve i t s own pa r a m e t e r s a nd vi s i bi l i t y */ s t a t i c z e nd_f unc t i on_e nt r y ut i l _di r _c l a s s _f unc t i ons [ ] = { PHP_M E( di r , __c ons t r uc t , a r gi nf o_di r ___c ons t r uc t , ZEND_ACC_CTOR | ZEND_ACC_PUBLI C) PHP_M E( di r , r ewi nd, NULL, ZEND_ACC_PUBLI C) PHP_M E( di r , has M
PHP_M E( di r , key, NULL, ZEND_ACC_PUBLI C) PHP_M E( di r , c ur r e nt , NULL, ZEND_ACC_PUBLI C) PHP_M E( di r , next , NULL, ZEND_ACC_PUBLI C) PHP_M E( di r , get Pa t h, NULL, ZEND_ACC_PUBLI C) {NULL, NULL, NULL} };
PHP Extension Writing 87 Börger, Schlüter / * de c l a r e t he c l a s s ha ndl e r s */ s t a t i c z e nd_obj e c t _ha ndl e r s ut i l _di r _ha ndl er s ; / * de c a l r e t he c l a s s e nt r y */ s t a t i c z e nd_c l a s s _e nt r y *ut i l _c e _di r ; / * t he ove r l oade d c l a s s s t r uct ur e */ / * ove r l oa di ng t he s t r uct ur e r e s ul t s i n t he ne e d of ha vi ng de di c a t e d cr e a t i n/ c l oni ng/ de s t r uc t i on f unc t i ons */ t ype de f s t r uc t _ut i l _di r _obj ec t { z e nd_obj e c t s t d; php_s t r e a m *di r p; php_s t r e a m _di r e nt e nt r y; c ha r *pa t h; i nt i nde x; } ut i l _di r _obj e c t ;
Inherit zend_object by placing it as first member of your object struct
PHP Extension Writing 88 Börger, Schlüter
z e nd_obj e c t _va l ue ut i l _di r _obj ec t _ne w( ze nd_cl a s s _e nt r y *c e TSRM LS_DC) { z e nd_obj e c t _va l ue r e t va l ; ut i l _di r _obj ec t *i nt e r n; i nt e r n = e c a l l oc ( 1, s i z eof ( ut i l _di r _obj e c t ) ) ; z e nd_obj e c t _s t d_i ni t ( & ( i nt e r n- >s t d) , c e TSRM LS_CC) ; z e nd_ha s h_c opy( i nt e r n- >s t d. pr ope r t i e s , & c e - >de f a ul t _pr oper t i e s , ( c opy_c t or _f unc _t ) z va l _a dd_r e f , NULL, s i z e of ( z va l *) ) ; r e t va l . ha ndl e = z end_obj e c t s _s t or e _put ( i nt e r n, ut i l _di r _obj ec t _dt or , NULL TSRM LS_CC) ; r e t va l . ha ndl er s = & ut i l _di r _ha ndl e r s ; r e t ur n r e t va l ; }
Initialize the whole struct (probably by using ecalloc())
PHP Extension Writing 89 Börger, Schlüter / * {{{ ut i l _di r _obj e c t _dt or */ / * c l os e a l l r e s our c e s and t he m e m
s t a t i c voi d ut i l _di r _obj e ct _dt or ( voi d *obj e c t , z e nd_obj e c t _ha ndl e ha ndl e TSRM LS_DC) { ut i l _di r _obj e ct *i nt e r n = ( ut i l _di r _obj e c t *) obj e c t ; z e nd_obj e c t _s t d_dt or ( & ( i nt e r n- >s t d) TSRM LS_CC) ; i f ( i nt e r n- >pat h) { e f r e e ( i nt e r n- >pa t h) ; } i f ( i nt e r n- >di r p) { php_s t r e a m _c l os e ( i nt e r n- >di r p) ; } e f r e e ( obj e c t ) ; } / * }}} */
PHP Extension Writing 90 Börger, Schlüter / * {{{ pr ot o s t r i ng di r : : ke y( ) Re t ur n c ur r e nt di r e nt r y */ PHP_M ETHOD( di r , ke y) { z va l *obj e c t = ge t Thi s ( ) ; ut i l _di r _obj e ct *i nt e r n = ( ut i l _di r _obj e c t *) z e nd_obj e c t _s t or e _ge t _obj e c t ( obj e c t TSRM LS_CC) ; i f ( i nt e r n- >di r p) { RETURN_LONG( i nt e r n- >i ndex) ; } e l s e { RETURN_FALSE; } } / * }}} */
PHP Extension Writing 91 Börger, Schlüter / * {{{ pr ot o voi d di r : : __c ons t r uc t ( s t r i ng pa t h) Cons t r uc t s a ne w di r i t e r a t or f r om a pa t h. */ PHP_M ETHOD( di r , __c ons t r uc t ) { ut i l _di r _obj e ct *i nt e r n; c ha r *pa t h; i nt l e n; i f ( z e nd_pa r s e_pa r a m e t e r s ( ZEND_NUM _ARGS( ) TSRM LS_CC, " s " , & pa t h, & l e n) == SUCCESS) { i nt e r n = ( ut i l _di r _obj e ct *) z e nd_obj e c t _s t or e _ge t _obj e c t ( ge t Thi s ( ) TSRM LS_CC) ; ut i l _di r _ope n( i nt e r n, pat h TSRM LS_CC) ; } } / * }}} */
In this case we chose to either finish initialization in the constructor or throw an exception.
PHP Extension Writing 92 Börger, Schlüter / * {{{ pr ot o voi d di r : : __c ons t r uc t ( s t r i ng pa t h) Cons t r uc t s a ne w di r i t e r a t or f r om a pa t h. */ PHP_M ETHOD( di r , __c ons t r uc t ) { ut i l _di r _obj e ct *i nt e r n; c ha r *pa t h; i nt l e n; php_s e t _e r r or _ha ndl i ng( EH_THROW , z e nd_e xc e pt i on_ge t _de f a ul t ( ) TSRM LS_CC) ; i f ( z e nd_pa r s e_pa r a m e t e r s ( ZEND_NUM _ARGS( ) TSRM LS_CC, " s " , & pa t h, & l e n) == SUCCESS) { i nt e r n = ( ut i l _di r _obj e ct *) z e nd_obj e c t _s t or e _ge t _obj e c t ( ge t Thi s ( ) TSRM LS_CC) ; ut i l _di r _ope n( i nt e r n, pat h TSRM LS_CC) ; } php_s e t _e r r or _ha ndl i ng( EH_NORM AL, NULL TSRM LS_CC) ; } / * }}} */
In this case we chose to either finish initialization in the constructor or throw an exception.
PHP Extension Writing 93 Börger, Schlüter / * {{{ */ s t a t i c i nt z e nd_s t d_c a s t _obj ec t _t os t r i ng( z va l *r e a dobj , z va l *wr i t e obj , i nt t ype TSRM LS_DC) { z va l *r e t va l == NULL; i f ( t ype == I S_STRI NG) { z e nd_c a l l _m e t hod_wi t h_0_pa r a m s ( & r e a dobj , NULL, NULL, " __t os t r i ng" , & r e t va l ) ; i f ( r e t va l ) { i f ( Z_TYPE_P( r e t va l ) ! = I S_STRI NG) { z e nd_e r r or ( E_ERROR, " M e t hod % s : : __t oSt r i ng( ) m us t " " r e t ur n a s t r i ng va l ue " , Z_OBJ CE_P( r e a dobj ) - >na m e ) ; } } e l s e { M AKE_STD_ZVAL( r e t va l ) ; ZVAL_EM PTY_STRI NG( r e t va l ) ; } ZVAL_ZVAL( wr i t e obj , r e t va l , 1, 1) ; I NI T_PZVAL( wr i t e obj ) ; } r e t ur n r e t va l ? SUCCESS : FAI LURE; } / * }}} */
PHP Extension Writing 94 Börger, Schlüter
PHP Extension Writing 95 Börger, Schlüter t ype de f s t r uc t _z e nd_obj e c t _ha ndl e r s { / * ge ne r a l obj e c t f unc t i ons */ z e nd_obj e c t _a dd_r e f _t a dd_r e f ; z e nd_obj e c t _del _r e f _t de l _r e f ; z e nd_obj e c t _del e t e _obj _t de l e t e _obj ; / * i ndi vi dua l obj e c t f unc t i ons */ z e nd_obj e c t _c l one _obj _t c l one _obj ; z e nd_obj e c t _r ea d_pr ope r t y_t r e a d_pr ope r t y; z e nd_obj e c t _wr i t e _pr ope r t y_t wr i t e _pr ope r t y; z e nd_obj e c t _r ea d_di m e ns i on_t r e a d_di m e ns i on; z e nd_obj e c t _wr i t e _di m e ns i on_t wr i t e _di m e ns i on; z e nd_obj e c t _get _pr ope r t y_pt r _pt r _t ge t _pr ope r t y_pt r _pt r ; z e nd_obj e c t _get _t ge t ; z e nd_obj e c t _s et _t s e t ; z e nd_obj e c t _has _pr ope r t y_t ha s _pr ope r t y; z e nd_obj e c t _uns e t _pr ope r t y_t uns e t _pr ope r t y; z e nd_obj e c t _uns e t _di m e ns i on_t uns e t _di m e ns i on; z e nd_obj e c t _get _pr ope r t i e s _t ge t _pr ope r t i e s ; z e nd_obj e c t _get _m e t hod_t ge t _m e t hod; z e nd_obj e c t _c al l _m e t hod_t c a l l _m e t hod; z e nd_obj e c t _get _c ons t r uct or _t ge t _c ons t r uc t or ; z e nd_obj e c t _get _c l a s s _e nt r y_t ge t _c l a s s _e nt r y; z e nd_obj e c t _get _c l a s s _nam e _t ge t _c l a s s _na m e; z e nd_obj e c t _c om pa r e _t c om pa r e _obj e c t s ; z e nd_obj e c t _c as t _t c a s t _obj e c t ; z e nd_obj e c t _c ount _e l e m e nt s _t c ount _e l e m e nt s ; } z e nd_obj e c t _ha ndl e r s ;
Don't touch these Keep or inherit
PHP Extension Writing 96 Börger, Schlüter
PHP Extension Writing 97 Börger, Schlüter
PHP Extension Writing 98 Börger, Schlüter / * de f i ne a n ove r l oa de d i t e r at or s t r uc t ur e */ t ype de f s t r uc t { z e nd_obj e c t _i t e r a t or i nt e r n; z va l *cur r e nt ; } ut i l _di r _i t ; s t a t i c voi d ut i l _di r _i t _dt or ( z e nd_obj e c t _i t e r a t or *i t e r TSRM LS_DC) ; s t a t i c i nt ut i l _di r _i t _va l i d( z e nd_obj e c t _i t e r a t or *i t e r TSRM LS_DC) ; s t a t i c voi d ut i l _di r _i t _c ur r ent _da t a ( z e nd_obj e c t _i t e r a t or *i t e r , z va l ***da t a TSRM LS_DC) ; s t a t i c i nt ut i l _di r _i t _cur r e nt _ke y( z e nd_obj e c t _i t e r a t or *i t e r , c ha r **s t r _ke y, ui nt *s t r _ke y_l e n, ul ong *i nt _ke y TSRM LS_DC) ; s t a t i c voi d ut i l _di r _i t _m
TSRM LS_DC) ; s t a t i c voi d ut i l _di r _i t _r e wi nd( z e nd_obj e c t _i t e r a t or *i t e r TSRM LS_DC) ; / * i t e r a t or handl e r t a bl e */ z e nd_obj e c t _i t e r a t or _f unc s ut i l _di r _i t _f uncs = { ut i l _di r _i t _dt or , ut i l _di r _i t _val i d, ut i l _di r _i t _c ur r e nt _da t a, ut i l _di r _i t _c ur r e nt _ke y, ut i l _di r _i t _m
ut i l _di r _i t _r ewi nd, NULL / * i nva l i da t e c ur r ent */ }; / * }}} */
PHP Extension Writing 99 Börger, Schlüter / * {{{ ut i l _di r _ge t _i t e r a t or */ z e nd_obj e c t _i t e r a t or *ut i l _di r _ge t _i t e r a t or ( z e nd_c l a s s _e nt r y *c e , z va l *obj e c t , i nt by_r e f TSRM LS_DC) { ut i l _di r _i t *i t e r a t or = e m a l l oc ( s i z e of ( ut i l _di r _i t ) ) ; i f ( by_r e f ) { z e nd_e r r or ( E_ERROR, “ I t er a t or i nva l i d i n f or e a c h by r e f " ) ; } Z_ADDREF_P( obj e c t ) ; i t e r a t or - >i nt er n. da t a = ( voi d*) obj e c t ; i t e r a t or - >i nt er n. f unc s = & ut i l _di r _i t _f unc s ; i t e r a t or - >c ur r e nt = NULL; r e t ur n ( z e nd_obj e c t _i t e r a t or *) i t e r a t or ; } / * }}} */
PHP Extension Writing 100 Börger, Schlüter / * {{{ ut i l _di r _i t _dt or */ s t a t i c voi d ut i l _di r _i t _dt or ( z e nd_obj e c t _i t e r a t or *i t e r TSRM LS_DC) { ut i l _di r _i t *i t e r a t or = ( ut i l _di r _i t *) i t e r ; z va l *i nt e r n = ( zva l *) i t e r a t or - >i nt er n. da t a ; i f ( i t e r a t or - >c ur r e nt ) { z va l _pt r _dt or ( & i t e r a t or - >c ur r e nt ) ; } z va l _pt r _dt or ( & i nt e r n) ; e f r e e ( i t e r a t or ) ; } / * }}} */
PHP Extension Writing 101 Börger, Schlüter / * {{{ ut i l _di r _i t _c ur r ent */ s t a t i c voi d ut i l _di r _i t _c ur r e nt ( ut i l _di r _i t *i t e r a t or , ut i l _di r _obj e c t *obj e c t TSRM LS_DC) { i f ( i t e r a t or - >c ur r e nt ) { z va l _pt r _dt or ( & i t e r a t or - >c ur r e nt ) ; } M AKE_STD_ZVAL( i t e r a t or - >c ur r ent ) ; i f ( obj e c t - >di r p) { ZVAL_STRI NG( i t e r a t or - >c ur r e nt , obj e c t - >e nt r y. d_na m e , 1) ; } e l s e { ZVAL_FALSE( i t er a t or - >c ur r e nt ) ; } } / * }}} */
PHP Extension Writing 102 Börger, Schlüter / * {{{ ut i l _di r _i t _va l i d */ s t a t i c i nt ut i l _di r _i t _val i d( z e nd_obj e c t _i t e r a t or *i t er TSRM LS_DC) { ut i l _di r _i t *i t e r a t or = ( ut i l _di r _i t *) i t e r ; ut i l _di r _obj e ct *obj e c t = ( ut i l _di r _obj e c t *) z e nd_obj e c t _s t or e _ge t _obj e c t ( ( z va l *) i t e r a t or - >i nt e r n. da t a TSRM LS_CC) ; r e t ur n obj e c t - >di r p & &
e [ 0] ! = ' \ 0' ? SUCCESS : FAI LURE; } / * }}} */
Note: Return SUCCESS or FAI LURE not typical boolean
PHP Extension Writing 103 Börger, Schlüter / * {{{ ut i l _di r _i t _c ur r ent _key */ s t a t i c i nt ut i l _di r _i t _cur r e nt _ke y( z e nd_obj e c t _i t e r a t or *i t e r , c ha r **s t r _ke y, ui nt *s t r _ke y_l e n, ul ong *i nt _key TSRM LS_DC) { ut i l _di r _i t *i t e r a t or = ( ut i l _di r _i t *) i t e r ; z va l *i nt e r n = ( z va l *) i t e r a t or - >i nt e r n. da t a ; ut i l _di r _obj e ct *obj e ct = ( ut i l _di r _obj e ct *) z e nd_obj e c t _s t or e _ge t _obj e c t ( i nt e r n TSRM LS_CC) ; *i nt _ke y = obj e c t - >i nde x; r e t ur n HASH_KEY_I S_LONG; } / * }}} */
Integer: H ASH _K EY_I S_LO NG Set ul ong * to the integer value String: H ASH _K EY_I S_STRI NG Set ui nt * to string length + 1 Set c har ** to copy of string (e s t r [ n] dup)
PHP Extension Writing 104 Börger, Schlüter / * {{{ ut i l _di r _i t _c ur r ent _dat a */ s t a t i c voi d ut i l _di r _i t _c ur r ent _da t a ( z e nd_obj e c t _i t e r a t or *i t e r , z va l ***da t a TSRM LS_DC) { ut i l _di r _i t *i t e r a t or = ( ut i l _di r _i t *) i t e r ; *da t a = & i t e r at or - >c ur r ent ; } / * }}} */
PHP Extension Writing 105 Börger, Schlüter / * {{{ ut i l _di r _i t _c ur r ent _dat a */ s t a t i c voi d ut i l _di r _i t _c ur r ent _da t a ( z e nd_obj e c t _i t e r a t or *i t e r , z va l ***da t a TSRM LS_DC) { ut i l _di r _i t *i t e r a t or = ( ut i l _di r _i t *) i t e r ; ut i l _di r _obj e ct *obj e c t ; i f ( ! i t e r a t or - >c ur r e nt ) {
( z va l *) i t e r a t or - >i nt e r n. da t a TSRM LS_CC) ; ut i l _di r _i t _c ur r e nt ( i t e r a t or , obj e c t TSRM LS_CC) ; } *da t a = & i t e r at or - >c ur r ent ; } / * }}} */
PHP Extension Writing 106 Börger, Schlüter / * {{{ ut i l _di r _i t _m
s t a t i c voi d ut i l _di r _i t _m
LS_DC) { ut i l _di r _i t *i t e r at or = ( ut i l _di r _i t *) i t e r ; z va l *i nt e r n = ( z va l *) i t e r a t or - >i nt e r n. da t a ; ut i l _di r _obj e ct *obj e ct = ( ut i l _di r _obj e ct *) z e nd_obj e c t _s t or e _ge t _obj e c t ( i nt e r n TSRM LS_CC) ;
i f ( ! obj e c t - >di r p | | ! php_s t r e a m _r e a ddi r ( obj e c t - >di r p, &
{
e [ 0] = ' \ 0' ; } ut i l _di r _i t _c ur r e nt ( i t e r a t or , obj e c t TSRM LS_CC) ; } / * }}} */
PHP Extension Writing 107 Börger, Schlüter / * {{{ ut i l _di r _i t _r e wi nd */ s t a t i c voi d ut i l _di r _i t _r ewi nd( z e nd_obj e ct _i t e r a t or *i t e r TSRM LS_DC) { ut i l _di r _i t *i t e r a t or = ( ut i l _di r _i t *) i t e r ; z va l *i nt e r n = ( z va l *) i t e r a t or - >i nt e r n. da t a ; ut i l _di r _obj e ct *obj e c t = ( ut i l _di r _obj e c t *) z e nd_obj e c t _s t or e _ge t _obj e c t ( i nt e r n TSRM LS_CC) ;
i f ( obj e c t - >di r p) { php_s t r e a m _r e wi nddi r ( obj e c t - >di r p) ; } i f ( ! obj e c t - >di r p | | ! php_s t r e a m _r e a ddi r ( obj e c t - >di r p, &
{
e [ 0] = ' \ 0' ; } ut i l _di r _i t _c ur r e nt ( i t e r a t or , obj e c t TSRM LS_CC) ; } / * }}} */
PHP Extension Writing 108 Börger, Schlüter
PHP Extension Writing 109 Börger, Schlüter