pass_rest_by_refphpempty

phpempty  时间:2021-05-23  阅读:()
PHPExtensionWritingMarcusBrgerJohannesSchlüterPHPQuebec2009PHPExtensionWriting2Brger,SchlüterCreatingPHP5ExtensionPHPLifecycleAddingobjectsAddingiteratorstoobjectsPHPExtensionWriting3Brger,SchlüterTextinyellowTextyoushoulduseaspresentedTextingreenTextthatyouhavetoreplaceyourextExtensionnameinlowercaseYOUREXTExtensionnameinuppercaseYourExtExtensionnameinmixedcase(camelCaps)HowtheslidesworkUpperpartcontainssomehelpfulhintsLowerpartshowsccodeonbluebackgroundSomespecialexplanationuseredtextboxesPHPExtensionWriting4Brger,SchlüterPartICreatingPHP5ExtensionsHowPHPhandlesdataHowtocreateyourownextensionskeletonHowtocreateyourownfunctionsHowtoworkwitharraysandhashtablesPHPExtensionWriting5Brger,Schlütertypedefstruct_zval_struct{zvalue_valuevalue;zend_uintrefcount;zend_uchartype;zend_ucharis_ref;}zval;InPHPallvaluesarezval'stypedefunion_zvalue_value{longlval;doubledval;struct{char*val;intlen;}str;HashTable*ht;zend_object_valueobj;}zvalue_value;IS_NULLIS_LONGIS_DOUBLEIS_BOOLIS_ARRAYIS_OBJECTIS_STRINGIS_RESOURCEPHPExtensionWriting6Brger,Schlütertypedefstruct_zval_struct{zvalue_valuevalue;zend_uintrefcount;zend_uchartype;zend_ucharis_ref;}zval;InPHPallvaluesarezval'sUserspacenotionof"Reference"0==Notareference1==IsareferenceHowmany"labels"areassociatedwiththiszvalPHPExtensionWriting7Brger,Schlütertypedefstruct_zval_struct{zvalue_valuevalue;zend_uintrefcount;zend_uchartype;zend_ucharis_ref;}zval;CopyOnWriteHasavalueof0(zero)zvalsharedby1ormorelabelsIfonelabelwantstomakeachange,itmustleaveotherlabelswiththeoriginalvalue.
$a=123;$b=$a;$b=456;value.
lval=123refcount=2type=IS_LONGis_ref=0$a$bPHPExtensionWriting8Brger,Schlütertypedefstruct_zval_struct{zvalue_valuevalue;zend_uintrefcount;zend_uchartype;zend_ucharis_ref;}zval;CopyOnWriteHasavalueof0(zero)zvalsharedby1ormorelabelsIfonelabelwantstomakeachange,itmustleaveotherlabelswiththeoriginalvalue.
$a=123;$b=$a;$b=456;value.
lval=123refcount=1type=IS_LONGis_ref=0$avalue.
lval=456refcount=1type=IS_LONGis_ref=0$bPHPExtensionWriting9Brger,Schlütertypedefstruct_zval_struct{zvalue_valuevalue;zend_uintrefcount;zend_uchartype;zend_ucharis_ref;}zval;FullReferenceHasavalueof1(one)zvalsharedby1ormorelabelsIfonelabelwantstomakeachange,itdoesso,causingotherlabelstoseethenewvalue.
$a=123;$b=&$a;$b=456;value.
lval=123refcount=2type=IS_LONGis_ref=1$a$bPHPExtensionWriting10Brger,Schlütertypedefstruct_zval_struct{zvalue_valuevalue;zend_uintrefcount;zend_uchartype;zend_ucharis_ref;}zval;FullReferenceHasavalueof1(one)zvalsharedby1ormorelabelsIfonelabelwantstomakeachange,itdoesso,causingotherlabelstoseethenewvalue.
$a=123;$b=&$a;$b=456;value.
lval=456refcount=2type=IS_LONGis_ref=1$a$bPHPExtensionWriting11Brger,SchlüterCreatingPHP5ExtensionsMostPHP4extswillbuildinPHP5w/oChangesext_skelcanbeusedtogenerateabasicskeletonmarcus@zaphodsrc/php5/ext$.
/ext_skel--extname=utilCreatingdirectoryutilCreatingbasicfiles:config.
m4.
cvsignoreutil.
cphp_util.
hCREDITSEXPERIMENTALtests/001.
phptutil.
php[done].
Touseyournewextension,youwillhavetoexecutethefollowingsteps:1.
$cd.
.
2.
$viext/util/config.
m43.
$.
/buildconf--force4.
$.
/configure--[with|enable]-util5.
$make6.
$.
/sapi/cli/php-fext/util/util.
php7.
$viext/util/util.
c8.
$makeRepeatsteps3-6untilyouaresatisfiedwithext/util/config.
m4andstep6confirmsthatyourmoduleiscompiledintoPHP.
Then,startwritingcodeandrepeatthelasttwostepsasoftenasnecessary.
Necessaryfornoncvssource(e.
g.
releasepackages)PHPExtensionWriting12Brger,SchlüterFilesinyourextensionYouneedatleasttwocodefilesphp_yourext.
hTheheaderneededbyphpphp_yourext.
cThemainextensioncode('php_'prefixfor.
cisnotnecessary)Youneedtwoconfigurationfilesconfig.
m4Usedunder*nixconfig.
w32UsedunderwindowsOptionalfiles.
cvsignoreListoffilestobeignoredbyCVSCREDITSFirstlineextname2ndlineallauthorsEXPERIMENTALIfavailabletheAPIisnotyetstablepackage2.
xmlRequiredforPECLextensionsREADMEProbablygoodtoprovidesomelinesPHPExtensionWriting13Brger,Schlüterdnl$Id:$dnlconfig.
m4forextensionYOUREXTPHP_ARG_ENABLE(yourext,enableYourExtsuppport,[--enable-yourextEnableYourExt],no)iftest"$PHP_YOUREXT"!
="no";thenAC_DEFINE(HAVE_YOUREXT,1,[WhetherYourExtispresent])PHP_NEW_EXTENSION(yourext,php_yourext.
c,$ext_shared)ficonfig.
m4PHPDevispickyaboutcodingstyleReadCODING_STANDARDSinphp-srcWatchyourwhitespaceAlignyourPHP_ARG_ENABLEoutputMakeyourextensiondefaultdisabled'phpize'or'pearinstall'willenableitautomaticallyPHPExtensionWriting14Brger,Schlüterconfig.
m4Youcanpreventtheextfrombecomingshareddnl$Id:$dnlconfig.
m4forextensionYOUREXTPHP_ARG_ENABLE(yourext,enableYourExtsuppport,[--enable-yourextEnableYourExt],no)iftest"$PHP_YOUREXT"!
="no";theniftest"$ext_shared"="yes";thenAC_MSG_ERROR(CannotbuildYOUREXTasasharedmodule)fiAC_DEFINE(HAVE_YOUREXT,1,[WhetherYourExtispresent])PHP_NEW_EXTENSION(yourext,php_yourext.
c,$ext_shared)fiPHPExtensionWriting15Brger,Schlüterconfig.
w32WindowsconfigurationusesJScript//$Id:$//vim:ft=javascriptARG_ENABLE("yourext","YourExtsupport","yes");if(PHP_YOUREXT=="yes"){if(PHP_YOUREXT_SHARED){ERROR("YOUREXTcannotbecompiledasasharedext");}AC_DEFINE("HAVE_YOUREXT",1,"YourExtsupport");EXTENSION("yourext","php_yourext.
c");}PHPExtensionWriting16Brger,SchlüterExtension.
hfileDeclaresdataforstaticlinkingandsymbolexports/*License,Author,CVS-Tag,Etc.
.
.
*/#ifndefPHP_YOUREXT_H#definePHP_YOUREXT_H#include"php.
h"externzend_module_entryyourext_module_entry;#definephpext_yourext_ptr&yourext_module_entry/*Onlyneededifyou'llbeexportingsymbols*/#ifdefPHP_WIN32#defineYOUREXT_API__declspec(dllexport)#else#defineYOUREXT_API#endif/*Placeforglobalsdefinition*/#endif/*PHP_YOUREXT_H*/PHPExtensionWriting17Brger,SchlüterLayoutofthe.
cfileHeader:License,Authors,CVS-Tag,.
.
.
IncludesStructuresanddefinesnotinheaderHelperFunctionsPHPFunctionsGlobalsHandlingMINFOMINIT,MSHUTDOWNRINIT,RSHUTDOWNFunctiontableModuleEntryPHPExtensionWriting18Brger,SchlüterIncludesIncludepath://Zend/main/ext/#ifdefHAVE_CONFIG_H#include"config.
h"#endif#include"php.
h"#include"php_ini.
h"#include"ext/standard/info.
h"#include"ext/standard/php_string.
h"#include"php_yourext.
h"PHPExtensionWriting19Brger,Schlütertypedefstruct_php_yourext_data{inttype;char*name;intname_len;php_stream*stream;}php_yourext_data;#definePHP_YOUREXT_MEANING42#definePHP_YOUREXT_COLOR"purple"#definePHP_YOUREXT_STRLEN(v)(vstrlen(v):0)StructuresanddefinesnotinheaderWhateveryouwantLocalstoragestructuresConstantsMacrosPHPExtensionWriting20Brger,SchlüterHelperFunctionsUseTSRMLS_xxaslastfunctionparameterWhendealingwithPHPDataUse--enable-maintainer-ztswhenbuildingPHPUsestaticorinlineIfyouneedthefuntiononlyinyour.
cfileUsePHPAPI/YOREXT_APIIfyouplantousethefunctionsinotherextensionsPHPExtensionWriting21Brger,Schlüterstaticvoidmy_helper(TSRMLS_D);staticvoidsome_function(TSRMLS_D){my_helper(TSRMLS_C);}HelperFunctionsUseTSRMLS_xxaslastfunctionparameterWhendealingwithPHPDataTSRMLS_DindeclarationsasonlyparamTSRMLS_Cinuses(calls)asonlyparamPHPExtensionWriting22Brger,Schlüterstaticvoidmy_helper(void*pTSRMLS_DC);staticvoidsome_function(void*pTSRMLS_DC){my_helper(pTSRMLS_CC);}HelperFunctionsUseTSRMLS_xxaslastfunctionparameterWhendealingwithPHPDataTSRMLS_DindeclarationsasonlyparamTSRMLS_DCindeclarationsafterlastparamw/ocommaTSRMLS_Cinuses(calls)asonlyparamTSRMLS_CCinusesafterlastparamw/ocommaPHPExtensionWriting23Brger,Schlüterstaticvoidmy_helper(char*p,intp_lenTSRMLS_DC);staticvoidsome_function(char*p){intp_len;TSRMLS_FETCH();p_len=strlen(p);my_helper(p,p_lenTSRMLS_CC);}HelperFunctionsUseTSRMLS_xxaslastfunctionparameterWhendealingwithPHPDataTSRMLS_DindeclarationsasonlyparamTSRMLS_DCindeclarationsafterlastparamw/ocommaTSRMLS_CinimplementationsasonlyparamTSRMLS_CCinimpl.
afterlastparamw/ocommaTSRMLS_FETCHcreateaTSRMkey,mustfollowlastlocalvarPHPExtensionWriting24Brger,SchlüterModuleEntryKeepseverythingtogetherTellsPHPhowto(de)initializetheextensionzend_module_entryyourext_module_entrySTANDARD_MODULE_HEADER,"YourExt",yourext_functions,PHP_MINIT(yourext),PHP_MSHUTDOWN(yourext),PHP_RINIT(yourext),PHP_RSHUTDOWN(yourext),PHP_MINFO(yourext),"0.
1",STANDARD_MODULE_PROPERTIES#ifCOMPILE_DL_YOUREXTZEND_GET_MODULE(yourext)#endiforNULLPHPExtensionWriting25Brger,SchlüterFunctionListExportsyourfunctionstouserspaceMustbeterminatedbyNULLtrippletzend_function_entryyourext_functions[PHP_FE(yourext_func1,yourext_args_func1)PHP_FE(yourext_func2,NULL)PHP_FALIAS(yourext_func3,yourext_func2,NULL)PHP_NAMED_FE(yourext_func4,_yourext_func4_impl,NULL){NULL,NULL,NULL}};PHPExtensionWriting26Brger,SchlüterstaticZEND_BEGIN_ARG_INFO_EX(yourext_args_func1,0,0,2)ZEND_ARG_INFO(0,param_name1)ZEND_ARG_ARRAY_INFO(1,param_name2)ZEND_END_ARG_INFO();ArgInfo/SignaturesThefunctiontableallowsspecifingthesignatureZEND_BEGIN_ARG_INFO_EX:name,pass_rest_by_ref,return_ref,required_argsZEND_ARG_INFO:pass_by_ref,nameZEND_ARG_PASS_INFO:pass_by_refZEND_ARG_ARRAY_INFO:pass_by_ref,nameZEND_ARG_OBJ_INFO:pass_by_ref,name,classname,allow_nullPHPExtensionWriting27Brger,Schlüter/*{{{prototypeyourext_name(params)Shortdescription*/PHP_FUNCTION(yourext_name){/*Localdeclarations*//*Parameterparsing*//*Actualcode*//*Returnvalue*/}PHPFunctionsNamespaceyourfunctionswithyourext'snameDocumentationisyourfriendAvoid//styleC++commentsAvoiddeclarationsinlinewithcodePHPExtensionWriting28Brger,SchlüterOutputtingContentDonotsendcontenttostdoutusePHP'soutputbufferingmechanismsphp_printf()worksjustlikeprintf()PHPWRITE()respectsbinarysafety/*{{{protonullyourext_hello_world()SayHello*/PHP_FUNCTION(yourext_hello_world){char*greeting="HelloWorld";php_printf("%s!
\n",greeting);PHPWRITE(greeting,strlen(greeting));php_printf("!
\n");}PHPExtensionWriting29Brger,Schlüterintzend_parse_parameters(intnum_argsTSRMLS_DC,char*type_spec,.
.
.
);intzend_parse_parameters_ex(intflags,intnum_argsTSRMLS_DC,char*type_spec,.
.
.
);flags0orZEND_PARSE_PARAMS_QUIETnum_argsuseZEND_NUM_ARGS()type_specsscanfliketypelist(thoughno%).
.
.
Referencestothetypesgivenintype_specreturnsSUCCESSorFAILUREincaseoffailureanerrorisalreadyissuedsononeedforZEND_WRONG_PARAM_COUNT()unlessusingZEND_PARSE_PARAMS_QUIETParsingparameterszend_parse_parametersistheeasywayofparsingPHPExtensionWriting30Brger,Schlütertype_specsscanfliketypelist(thoughno%)llonglong*ddoubledouble*bbooleanzend_bool*aarrayzval**oobjectzval**Oobjectzval**,zend_class_entry*Objectmustbederivedfromgivenclasssstringchar**,int*Youreceivestringandlengthrresourcezval**zzvalzval**Zzval-refzval***|rightpartisoptional/nextparamgetsseparatedifnotreference!
NextparamreturnsNULLifparamtypeIS_NULLParsingparametersPHPExtensionWriting31Brger,SchlüterParsingParameters/*{{{protonullyourext_hello(stringname)Greetbyname*/PHP_FUNCTION(yourext_hello){char*name;intname_len;if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"s",&name,&name_len)==FAILURE){return;}php_printf("Hello%s!
\n",name);}PHPExtensionWriting32Brger,SchlüterReturningValuesMarkingsuccess/*{{{protoboolyourext_hello(stringname)Greetbyname*/PHP_FUNCTION(yourext_hello){char*name;intname_len;if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"s",&name,&name_len)==FAILURE){return;}php_printf("Hello%s!
\n",name);RETURN_TRUE;}MakesthereturnvalueNULLPHPExtensionWriting33Brger,SchlüterReturningValuesSimplescalarsuseintuitiveRETURN_*()macrosRETURN_NULL();RETURN_BOOL(b);b:0=>FALSE,non-0=>TRUERETURN_TRUE;RETURN_BOOL(1)RETURN_FALSE;RETURN_BOOL(0)RETURN_LONG(l);l:IntegervalueRETURN_DOUBLE(d);d:FloatingpointvaluePHPExtensionWriting34Brger,SchlüterReturningValuesStringsareslightlymorecomplexThestringvaluemust"belong"totheengineWillnotsurvivethedestructionofthezvalWillbefreedusingefree()Pass0(zero)forduptogiveitthestringPass1(one)forduptomakeacopy(duplicate)RETURN_STRING(str,dup)str:char*stringvaluedup:0/1flag,duplicatestringRETURN_STRINGL(str,len,dup)len:PredeterminedstringlengthRETURN_STRING("HelloWorld",1);RETURN_STRING(estrdup("HelloWorld"),0);RETURN_EMPTY_STRING();PHPExtensionWriting35Brger,SchlüterSettingReturningValuesRETURN_*()macrosautomaticallyexitfunction#defineRETURN_NULL(){RETVAL_NULL();return;}#defineRETURN_TRUE{RETVAL_TRUE;return;}#defineRETURN_FALSE{RETVAL_FALSE;return;}#defineRETURN_BOOL(b){RETVAL_BOOL(b);return;}#defineRETURN_LONG(l){RETVAL_LONG(l);return;}#defineRETURN_DOUBLE(d){RETVAL_DOUBLE(d);return;}#defineRETURN_STRING(str,dup)\{RETVAL_STRING(str,dup);return;}#defineRETURN_STRINGL(str,len,dup)\{RETVAL_STRINGL(str,len,dup);return;}#defineRETURN_EMPTY_STRING()\{RETVAL_EMPTY_STRING();return;}PHPExtensionWriting36Brger,SchlüterSettingReturningValuesRETURN_*()macrosautomaticallyexitfunctionRETVAL_*()familyworkthesamewithoutexiting#defineRETVAL_NULL()ZVAL_NULL(return_value)#defineRETVAL_TRUEZVAL_TRUE(return_value)#defineRETVAL_FALSEZVAL_FALSE(return_value)#defineRETVAL_BOOL(b)ZVAL_BOOL(return_value,b)#defineRETVAL_LONG(l)ZVAL_LONG(return_value,l)#defineRETVAL_DOUBLE(d)ZVAL_DOUBLE(return_value,d)#defineRETVAL_STRING(str,dup)\ZVAL_STRING(return_value,str,dup)#defineRETVAL_STRINGL(str,len,dup)\ZVAL_STRINGL(return_value,str,len,dup)#defineRETVAL_EMPTY_STRING()\ZVAL_EMPTY_STRING(return_value)PHPExtensionWriting37Brger,SchlüterSettingReturningValuesRETURN_*()macrosautomaticallyexitfunctionRETVAL_*()familyworkthesamewithoutexitingZVAL_*()familyworkonspecificzval(later)#defineRETVAL_NULL()ZVAL_NULL(return_value)#defineRETVAL_TRUEZVAL_TRUE(return_value)#defineRETVAL_FALSEZVAL_FALSE(return_value)#defineRETVAL_BOOL(b)ZVAL_BOOL(return_value,b)#defineRETVAL_LONG(l)ZVAL_LONG(return_value,l)#defineRETVAL_DOUBLE(d)ZVAL_DOUBLE(return_value,d)#defineRETVAL_STRING(str,dup)\ZVAL_STRING(return_value,str,dup)#defineRETVAL_STRINGL(str,len,dup)\ZVAL_STRINGL(return_value,str,len,dup)#defineRETVAL_EMPTY_STRING()\ZVAL_EMPTY_STRING(return_value)PHPExtensionWriting38Brger,SchlüterExample1Invertingasinglebooleanparameter/*{{{protoboolyourext_invert(boolb)Invertabooleanparameter*/PHP_FUNCTION(yourext_invert){zend_boolb;if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"b",&b)==FAILURE){return;}b=b0:1;RETURN_BOOL(b);}PHPExtensionWriting39Brger,SchlüterExample2Incrementingavaluewithanoptionalmaximum/*{{{protointyourext_increment(intv[,intmax])Incrementavaluewithoptionalmaximum*/PHP_FUNCTION(yourext_increment){longn,nmax=LONG_MAX;if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"l|l",&n,&nmax)==FAILURE){RETURN_FALSE();}n=(n+1)%nmax;RETURN_LONG(n);}InitializeoptionalvaluesUsebracketsforoptionalvaluesAverticalbarseparatesoptionalandrequiredparametersPHPExtensionWriting40Brger,Schlüter#defineYOUREXT_VERSION_MAJOR0#defineYOUREXT_VERSION_MINOR1/*{{{protostringyourext_version()Retrieveyourextversion*/PHP_FUNCTION(yourext_version){char*ver;intlen;len=spprintf(&ver,0,"%d.
%d(%s)",YOUREXT_VERSION_MAJOR,YOUREXT_VERSION_MINOR,"$Id:$");RETURN_STRINGL(ver,len,0);}Example3ReturningsomegeneratedstringNeverusesprintf,useeithersnprintforspprintfNoneedtocopythestringPHPExtensionWriting41Brger,Schlüterintadd_assoc_long(zval*arg,char*key,longn);intadd_assoc_null(zval*arg,char*key);intadd_assoc_bool(zval*arg,char*key,intb);intadd_assoc_resource(zval*arg,char*key,intr);intadd_assoc_double(zval*arg,char*key,doubled);intadd_assoc_string(zval*arg,char*key,char*str,intdup);intadd_assoc_stringl(zval*arg,char*key,char*str,uintlen,intdup);intadd_assoc_zval(zval*arg,char*key,zval*value);DealingwitharraysToinitializeazvalasanarray:array_init(pzv)Toreturnanarrayuse:array_init(return_value)Toaddelementsusethefollowingadd_assoc_(ar,key,.
.
.
)add_assoc__ex(ar,key,key_len,.
.
.
)PHPExtensionWriting42Brger,Schlüterintadd_index_long(zval*arg,uintidx,longn);intadd_index_null(zval*arg,uintidx);intadd_index_bool(zval*arg,uintidx,intb);intadd_index_resource(zval*arg,uintidx,intr);intadd_index_double(zval*arg,uintidx,doubled);intadd_index_string(zval*arg,uintidx,char*str,intduplicate);intadd_index_stringl(zval*arg,uintidx,char*str,uintlength,intduplicate);intadd_index_zval(zval*arg,uintidx,zval*value);DealingwitharraysToconvertazvalintoanarray:array_init(pzv)Toreturnanarrayuse:array_init(return_value)Toaddelementsusethefollowingadd_assoc_(ar,key,.
.
.
)add_index_(ar,index,.
.
.
)PHPExtensionWriting43Brger,Schlüterintadd_next_index_long(zval*arg,longn);intadd_next_index_null(zval*arg);intadd_next_index_bool(zval*arg,intb);intadd_next_index_resource(zval*arg,intr);intadd_next_index_double(zval*arg,doubled);intadd_next_index_string(zval*arg,char*str,intduplicate);intadd_next_index_stringl(zval*arg,char*str,uintlength,intduplicate);intadd_next_index_zval(zval*arg,zval*value);DealingwitharraysToconvertazvalintoanarray:array_init(pzv)Toreturnanarrayuse:array_init(return_value)Toaddelementsusethefollowingadd_assoc_(ar,key,.
.
.
)add_index_(ar,index,.
.
.
)add_next_index_(ar,.
.
.
)PHPExtensionWriting44Brger,Schlüter/*{{{protoarrayyourext_version_array()Retrieveyourextversionasarray*/PHP_FUNCTION(yourext_version_array){char*ver;intlen=spprintf(&ver,0,"%d.
%d",YOUREXT_VERSION_MAJOR,YOUREXT_VERSION_MINOR);array_init(return_value);add_assoc_long(return_value,"major",YOUREXT_VERSION_MAJOR);add_assoc_long(return_value,"minor",YOUREXT_VERISON_MINOR);add_assoc_string(return_value,"cvs","$Id:$",1);add_assoc_stringl(return_value,"ver",ver,len,0);}Example4Returninganarraymakereturn_valueanarrayPHPExtensionWriting45Brger,Schlüter/*arKeyhashedusingDJBX33A*/ulongzend_get_hash_value(char*arKey,uintnKeyLength);/*count($ht)*/intzend_hash_num_elements(HashTable*ht);/*RemovesallelementsfromtheHashTable*/intzend_hash_clean(HashTable*ht);DealingwithaHashTableMultiplevaluesstoredinkey/valuepairsArraysarespecialHashTables(Symboltables)NumerickeysgetconvertedtostringsAllvaluesarezval*pointers.
PHPExtensionWriting46Brger,Schlüteradd_assoc_zval(arr,"foo",val);add_assoc_zval_ex(arr,"foo",sizeof("foo"),val);zend_symtable_update(Z_ARRVAL_P(arr),"foo",sizeof("foo"),&val,sizeof(zval*),NULL);AddingtoHashTablesadd_assoc/index_*()functionswrapzend_symtable_update()SymboltablekeysincludeterminatingNULLbytesizeof(key)vs.
strlen(key)PHPExtensionWriting47Brger,Schlüterintzend_hash_del(HashTable*ht,char*arKey,uintnKeyLen);intzend_hash_index_del(HashTable*ht,ulongh);intzend_symtable_del(HashTable*ht,char*arKey,uintnKeyLength);DeletingfromHashTablesYoucandeleteelements(SUCCESS/FAILURE)bykeybyhashindexbysymbolPHPExtensionWriting48Brger,Schlüterintzend_hash_exists(HashTable*ht,char*arKey,uintnKeyLength);intzend_hash_quick_exists(HashTable*ht,char*arKey,uintnKeyLength,ulongh);intzend_hash_index_exists(HashTable*ht,ulongh);intzend_symtable_exists(HashTable*ht,char*arKey,uintnKeyLength);SearchingHashTablesYoucancheckforexistanceofelements(0/1)bykeybyhashindexbyautomaticpreferenceofhashindexoverkey(len=0)bysymbolPHPExtensionWriting49Brger,Schlüterintzend_hash_find(HashTable*ht,char*arKey,uintnKeyLength,void**pData);intzend_hash_quick_find(HashTable*ht,char*arKey,uintnKeyLength,ulongh,void**pData);intzend_hash_index_find(HashTable*ht,ulongh,void**pData);intzend_symtable_find(HashTable*ht,char*arKey,uintnKeyLength,void**pData);SearchingHashTablesYoucanlookupelements(SUCCESS/FAILURE)bykeybyhashindexbyautomaticpreferenceofhashindexoverkey(len=0)bysymbolPHPExtensionWriting50Brger,Schlüterzval**tmp;if(zend_symtable_find(ht,"key",sizeof("key"),(void**)&tmp)==SUCCESS){/*Dosomethingwithtmp*/if(Z_TYPE_PP(tmp)==IS_STRING){PHPWRITE(Z_STRVAL_PP(tmp),Z_STRLEN_PP(tmp));}}SearchingHashTablesSymbolTablesstorezval*pointersWhenfetching,areferencetoazval**ispassedPHPExtensionWriting51Brger,SchlüterAccessingazvalZ_LVAL(zval)longvalueZ_BVAL(zval)zend_boolvalueZ_DVAL(zval)doublevalueZ_STRVAL(zval)char*valueZ_STRLEN(zval)intlengthZ_ARRVAL(zval)HashTable*onlyarrayZ_OBJ_HANDLE(zval)intobjidZ_OBJ_HT(zval)zend_object_handlers*objhandlersZ_OBJCE(zval)zend_class_entry*objclassZ_OBJPROP(zval)HashTable*propertiesZ_OBJ_HANDLER(zval,hf)Z_OBJ_HT((zval))->hfobjhandlerZ_RESVAL(zval)intresourceidZ_TYPE(zval)intIS_*HASH_OF(zval)HashTable*array+propsZ_*_P(zp)Z_*(*zp)Z_*_PP(zpp)Z_*(**zpp)PHPExtensionWriting52Brger,SchlüterReferencecountandis-refZ_REFCOUNT(zval)RetrievereferencecountZ_SET_REFCOUNT(zval,rc)SetreferencecounttoZ_ADDREF(zval)IncrementreferencecountZ_DELREF(zval)DecrementreferencecountZ_ISREF(zval)WhetherzvalisareferenceZ_SET_ISREF(zval)MakeszvalareferencevariableZ_UNSET_ISREF(zval)Resetstheis-referenceflagZ_SET_ISREF_TO(zval,is)Makezvalareferenceis!
=0Z_*_P(zp)Z_*(*zp)Z_*_PP(zpp)Z_*(**zpp)PHPExtensionWriting53Brger,SchlüterSettingtypesandvaluesZVAL_NULL(zp)IS_NULLJustsetthetypeZVAL_RESOURCE(zp,l)IS_RESOURCESettoresourceZVAL_BOOL(zp,b)IS_BOOLSettobooleanZVAL_FALSE(zp)IS_BOOLSettofalseZVAL_TRUE(zp)IS_BOOLSettotrueZVAL_LONG(zp,l)IS_LONGSettolongZVAL_DOUBLE(zp,d)IS_DOUBLESettodoubleZVAL_STRING(zp,s,dup)IS_STRINGSetstringZVAL_STRINGL(zp,s,l,dup)IS_STRINGSetstringandlengthZVAL_EMPTY_STRING(zp)IS_STRINGSetasemptystringZVAL_ZVAL(zp,zv,copy,dtor)Copythezvalanditstype.
Allowstocallcopying,necessaryforstringsetc.
Allowstodestruct(delref)theoriginalzval.
PHPExtensionWriting54Brger,SchlüterAllocateandInitializeazvalALLOC_ZVAL(zp)Allocateazvalusingemalloc()INIT_PZVAL(zp)Setreferencecountandisref0INIT_ZVAL(zval)InitializeandsetNULL,nopointerALLOC_INIT_ZVAL(zp)AllocateandinitializeazvalMAKE_STD_ZVAL(zp)Allocate,initializeandsetNULLExample:zval*val;ALLOC_INIT_ZVAL(val);ZVAL_STRINGL(val,"Myval",sizeof("myval")-1,1)PHPExtensionWriting55Brger,SchlüterDealingwithaHashTableHashtableshavebuiltin"foreach"functions/*array_walk($ht,$apply_func)*/voidzend_hash_apply(HashTable*ht,apply_func_tapply_funcTSRMLS_DC);/*array_walk($ht,$apply_func,$data)*/voidzend_hash_apply_with_argument(HashTable*ht,apply_func_arg_tapply_func,void*TSRMLS_DC);/*Multipleargumentversion,*Thisisalsotheonlyvariantwhichprovides*thekeytothecallback*/voidzend_hash_apply_with_arguments(HashTable*ht,apply_func_args_tapply_func,int,.
.
.
);PHPExtensionWriting56Brger,SchlüterDealingwithaHashTableHashtableshavebuiltin"foreach"functionsEachfunctionrequiresadifferenttypeofcallback/*pDestcontainsapointerto*what'sstoredintheHashTable*Sincethereisazval*inSymbolTables*wewindupwithazval**beingpassedaspDest*typedefint(*apply_func_t)(void*pDestTSRMLS_DC);typedefint(*apply_func_arg_t)(void*pDest,void*argumentTSRMLS_DC);typedefint(*apply_func_args_t)(void*pDest,intnum_args,va_listargs,zend_hash_key*hash_key);PHPExtensionWriting57Brger,SchlüterDealingwithaHashTableHashtableshavebuiltin"foreach"functionsEachfunctionrequiresadifferenttypeofcallbackCallbacksreturnoneofthreestatusvaluesPriorto5.
2.
1allnonzeroreturnvaluesresultindeletion/*ContinueitteratingtheHashTable*/#defineZEND_HASH_APPLY_KEEP0/*Removethiselement,butcontinueprocessing*/#defineZEND_HASH_APPLY_REMOVE1=5.
1void*pemalloc(size_tsize,intpersist);void*pecalloc(size_tnmemb,size_tsize,intpersist);void*perealloc(void*ptr,size_tsize,intpersist);void*pestrdup(char*str,intpersist);voidpefree(void*ptr,intpersist);void*safe_pemalloc(size_tnmemb,size_tsize,size_taddtl,intpersist);PHPExtensionWriting69Brger,SchlüterStoringGlobalValuesDoNOTstoretransientdataintheglobalscope!
ThreadedSAPIswillbreakstaticchar*errormsg=NULL;PHP_FUNCTION(yourext_unthreadsafe){longret;ret=do_something("value",&errormsg);if(errormsg){php_error_docref(NULLTSRMLS_CC,E_WARNING,"do_something()failedwith:%s",errormsg);free(errormsg);errormsg=NULL;}}PHPExtensionWriting70Brger,SchlüterZEND_BEGIN_MODULE_GLOBALS(yourext)char*str;intstrlen;longcounter;ZEND_END_MODULE_GLOBALS(yourext)#ifdefZTS#defineYOUREXT_G(v)\TSRMG(yourext_globals_id,zend_yourext_globals*,v)externintyourext_globals_id;#else#defineYOUREXT_G(v)(yourext_globals.
v)externzend_yourext_globalsyourext_globals;#endifGlobalstructin.
hProvideastructureandaccessmacrosPHPExtensionWriting71Brger,SchlüterZEND_DECLARE_MODULE_GLOBALS(yourext)staticvoidyourext_globals_ctor(zend_yourext_globals*globals){/*Initializeyourglobalstruct*/globals->str=NULL;globals->strlen=0;globals->counter=0;}staticvoidyourext_globals_dtor(zend_yourext_globals*globals){/*Cleanupanyallocatedglobals*/}GlobalHandlingin.
cProvidethestorage/idandctor/dtorfunctionsInitializercalledonceat(thread)startupDestructorcalledonceat(thread)shutdownAllocationsmadeheremustbepersistent(malloc'd)PHPExtensionWriting72Brger,SchlüterMINIT/MSHUTDOWNAllocatelocalstorageforglobalsinZTSmodeCallglobalsinitializationanddestructionasneededPHP_MINIT_FUNCTION(yourext){ZEND_INIT_MODULE_GLOBALS(yourext,yourext_globals_ctor,yourext_globals_dtor);returnSUCCESS;}PHP_MSHUTDOWN_FUNCTION(yourext){#ifndefZTSyourext_globals_dtor(&yourext_globalsTSRMLS_CC);#endifreturnSUCCESS;}PHPExtensionWriting73Brger,SchlüterRINIT/RSHUTDOWNInitializerequestspecificsettingsatRINITCleanuptheirvaluesatRSHUTDOWNPHP_RINIT_FUNCTION(yourext){/*Tracknumberoftimesthisthread/process*hasservicedrequests*/YOUREXT_G(counter)++;returnSUCCESS;}PHP_RSHUTDOWN_FUNCTION(yourext){if(YOUREXT_G(str)){efree(YOUREXT_G(str));YOUREXT_G(str)=NULL;}returnSUCCESS;}PHPExtensionWriting74Brger,SchlüterGlobalsAccessAccessglobalvaluesusingYOUREXT_G(v)macroPHP_FUNCTION(yourext_set_string){char*str;intstr_len;if(zend_parse_parameters(ZEND_NUM_ARGS(),"s",&str,&str_len)==FAILURE){return;}if(YOUREXT_G(str)){efree(YOUREXT_G(str));}YOUREXT_G(str)=estrndup(str,str_len);YOUREXT_G(strlen)=str_len;RETURN_TRUE;}PHPExtensionWriting75Brger,SchlüterGlobalsAccessAccessglobalvaluesusingYOUREXT_G(v)macroPHP_FUNCTION(yourext_get_string){if(YOUREXT_G(str)){RETURN_STRINGL(YOUREXT_G(str),YOUREXT_G(strlen),1);}else{RETURN_EMPTY_STRING();}}PHPExtensionWriting76Brger,SchlüterRegisteringconstsRegisterconstantsduringMINIT(usually)name_lenhereissizeof()ThusnamemustbearealstringDonotusestringvariables!
intzend_get_constant(char*name,uintname_len,zval*resultTSRMLS_DC);REGISTER_LONG_CONSTANT(name,lval,flags)REGISTER_DOUBLE_CONSTANT(name,dval,flags)REGISTER_STRING_CONSTANT(name,str,flags)REGISTER_STRINGL_CONSTANT(name,str,len,flags)intzend_register_constant(zend_constant*cTSRMLS_DC);/*Case-sensitive*/#defineCONST_CS(1create_object=util_dir_object_new;memcpy(&util_dir_handlers,zend_get_std_object_handlers(),sizeof(zend_object_handlers));util_dir_handlers.
clone_obj=util_dir_object_clone;zend_class_implements(util_ce_dirTSRMLS_CC,1,zend_ce_iterator);util_ce_dir->ce_flags|=ZEND_ACC_FINAL_CLASS;util_ce_dir->get_iterator=util_dir_get_iterator;returnSUCCESS;RegisteringObviouslyyouhavetoregisteryourclassAtemporaryzend_class_entryisnecessaryfirstAfterbasicregisteringyouhaveadedicatedpointerNowyouhavetospecifythec-levelconstructorfunctionProvideyourownhandlerfuncsorcopyandmodifydefaultsFinallyimplementinterfaces,setclassflags,specifyiteratorPHPExtensionWriting85Brger,Schlüterintzend_declare_class_constant(zend_class_entry*ce,char*name,size_tname_len,zval*valueTSRMLS_DC);intzend_declare_class_constant_long(zend_class_entry*ce,char*name,size_tname_len,longvalueTSRMLS_DC);intzend_declare_class_constant_bool(zend_class_entry*ce,char*name,size_tname_len,zend_boolvalueTSRMLS_DC);intzend_declare_class_constant_double(zend_class_entry*ce,char*name,size_tname_len,doublevalueTSRMLS_DC);intzend_declare_class_constant_stringl(zend_class_entry*ce,char*name,size_tname_len,char*val,size_tval_lenTSRMLS_DC);intzend_declare_class_constant_string(zend_class_entry*ce,char*name,size_tname_len,char*valueTSRMLS_DC);DeclaringclassconstantsYoucanregisterclassconstantsUsetargetzend_class_entrypointerUsesizeof()notstrlen()forconstnamePHPExtensionWriting86Brger,Schlüter/*declaremethodparameters,*/staticZEND_BEGIN_ARG_INFO(arginfo_dir___construct,0)ZEND_ARG_INFO(0,path)/*parametername*/ZEND_END_ARG_INFO();/*eachmethodcanhaveitsownparametersandvisibility*/staticzend_function_entryutil_dir_class_functions[]={PHP_ME(dir,__construct,arginfo_dir___construct,ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)PHP_ME(dir,rewind,NULL,ZEND_ACC_PUBLIC)PHP_ME(dir,hasMore,NULL,ZEND_ACC_PUBLIC)PHP_ME(dir,key,NULL,ZEND_ACC_PUBLIC)PHP_ME(dir,current,NULL,ZEND_ACC_PUBLIC)PHP_ME(dir,next,NULL,ZEND_ACC_PUBLIC)PHP_ME(dir,getPath,NULL,ZEND_ACC_PUBLIC){NULL,NULL,NULL}};DeclaringmethodsPHPExtensionWriting87Brger,Schlüter/*declaretheclasshandlers*/staticzend_object_handlersutil_dir_handlers;/*decalretheclassentry*/staticzend_class_entry*util_ce_dir;/*theoverloadedclassstructure*//*overloadingthestructureresultsintheneedofhavingdedicatedcreatin/cloning/destructionfunctions*/typedefstruct_util_dir_object{zend_objectstd;php_stream*dirp;php_stream_dirententry;char*path;intindex;}util_dir_object;class/objectstructsItisagoodpracticeto'inherit'zend_objectThatallowsyourclasstosupportnormalpropertiesThusyoudonotneedtooverwriteallhandlersInheritzend_objectbyplacingitasfirstmemberofyourobjectstructPHPExtensionWriting88Brger,Schlüterzend_object_valueutil_dir_object_new(zend_class_entry*ceTSRMLS_DC){zend_object_valueretval;util_dir_object*intern;intern=ecalloc(1,sizeof(util_dir_object));zend_object_std_init(&(intern->std),ceTSRMLS_CC);zend_hash_copy(intern->std.
properties,&ce->default_properties,(copy_ctor_func_t)zval_add_ref,NULL,sizeof(zval*));retval.
handle=zend_objects_store_put(intern,util_dir_object_dtor,NULLTSRMLS_CC);retval.
handlers=&util_dir_handlers;returnretval;}Objectcreation/cloningAllcatememoryforyourstructInitializethewholestruct(probablybyusingecalloc())InitializethebaseZendobjectCopydefaultpropertiesStoretheobjectAssignthehandlersPHPExtensionWriting89Brger,Schlüter/*{{{util_dir_object_dtor*//*closeallresourcesandthememoryallocatedfortheobject*/staticvoidutil_dir_object_dtor(void*object,zend_object_handlehandleTSRMLS_DC){util_dir_object*intern=(util_dir_object*)object;zend_object_std_dtor(&(intern->std)TSRMLS_CC);if(intern->path){efree(intern->path);}if(intern->dirp){php_stream_close(intern->dirp);}efree(object);ObjectdestructionFreepropertiesFreeallresourcesandfreeallallocatedmemoryFreememoryforobjectitselfPHPExtensionWriting90Brger,Schlüter/*{{{protostringdir::key()Returncurrentdirentry*/PHP_METHOD(dir,key){zval*object=getThis();util_dir_object*intern=(util_dir_object*)zend_object_store_get_object(objectTSRMLS_CC);if(intern->dirp){RETURN_LONG(intern->index);}else{RETURN_FALSE;}AsimplemethodMacrogetThis()givesyouaccessto$thisaszvalThereturnedzvalisusedtogetyourstructPHPExtensionWriting91Brger,Schlüter/*{{{protovoiddir::__construct(stringpath)Constructsanewdiriteratorfromapath.
*/PHP_METHOD(dir,__construct){util_dir_object*intern;char*path;intlen;if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"s",&path,&len)==SUCCESS){intern=(util_dir_object*)zend_object_store_get_object(getThis()TSRMLS_CC);util_dir_open(intern,pathTSRMLS_CC);}TheconstructorRememberthatyourobjectisalreadyfullyinitializedInthiscasewechosetoeitherfinishinitializationintheconstructororthrowanexception.
PHPExtensionWriting92Brger,Schlüter/*{{{protovoiddir::__construct(stringpath)Constructsanewdiriteratorfromapath.
*/PHP_METHOD(dir,__construct){util_dir_object*intern;char*path;intlen;php_set_error_handling(EH_THROW,zend_exception_get_default()TSRMLS_CC);if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"s",&path,&len)==SUCCESS){intern=(util_dir_object*)zend_object_store_get_object(getThis()TSRMLS_CC);util_dir_open(intern,pathTSRMLS_CC);}php_set_error_handling(EH_NORMAL,NULLTSRMLS_CC);TheconstructorRememberthatyourobjectisalreadyfullyinitializedInthiscasewechosetoeitherfinishinitializationintheconstructororthrowanexception.
ChangeerrorstoexceptionstosupportconstructorfailurePHPExtensionWriting93Brger,Schlüterstaticintzend_std_cast_object_tostring(zval*readobj,zval*writeobj,inttypeTSRMLS_DC){zval*retval==NULL;if(type==IS_STRING){zend_call_method_with_0_params(&readobj,NULL,NULL,"__tostring",&retval);if(retval){if(Z_TYPE_P(retval)!
=IS_STRING){zend_error(E_ERROR,"Method%s::__toString()must""returnastringvalue",Z_OBJCE_P(readobj)->name);}}else{MAKE_STD_ZVAL(retval);ZVAL_EMPTY_STRING(retval);}ZVAL_ZVAL(writeobj,retval,1,1);INIT_PZVAL(writeobj);}returnretvalSUCCESS:FAILURE;ObjectcastingPHPExtensionWriting94Brger,SchlüterOtherhandlerstooverloadObjectscanoverloadseveralhandlersArrayaccessPropertyaccessSerializingPHPExtensionWriting95Brger,Schlütertypedefstruct_zend_object_handlers{/*generalobjectfunctions*/zend_object_add_ref_tadd_ref;zend_object_del_ref_tdel_ref;zend_object_delete_obj_tdelete_obj;/*individualobjectfunctions*/zend_object_clone_obj_tclone_obj;zend_object_read_property_tread_property;zend_object_write_property_twrite_property;zend_object_read_dimension_tread_dimension;zend_object_write_dimension_twrite_dimension;zend_object_get_property_ptr_ptr_tget_property_ptr_ptr;zend_object_get_tget;zend_object_set_tset;zend_object_has_property_thas_property;zend_object_unset_property_tunset_property;zend_object_unset_dimension_tunset_dimension;zend_object_get_properties_tget_properties;zend_object_get_method_tget_method;zend_object_call_method_tcall_method;zend_object_get_constructor_tget_constructor;zend_object_get_class_entry_tget_class_entry;zend_object_get_class_name_tget_class_name;zend_object_compare_tcompare_objects;zend_object_cast_tcast_object;zend_object_count_elements_tcount_elements;}zend_object_handlers;Don'ttouchtheseKeeporinheritzend_object_handlersPHPExtensionWriting96Brger,SchlüterWhatelseIteratorsupportPHPExtensionWriting97Brger,SchlüterPartIVAddingIteratorstoobjectsProvideaniteratorstructureProvidethehandlersProvideaniteratorcreationfunctionPHPExtensionWriting98Brger,Schlüter/*defineanoverloadediteratorstructure*/typedefstruct{zend_object_iteratorintern;zval*current;}util_dir_it;staticvoidutil_dir_it_dtor(zend_object_iterator*iterTSRMLS_DC);staticintutil_dir_it_valid(zend_object_iterator*iterTSRMLS_DC);staticvoidutil_dir_it_current_data(zend_object_iterator*iter,zval***dataTSRMLS_DC);staticintutil_dir_it_current_key(zend_object_iterator*iter,char**str_key,uint*str_key_len,ulong*int_keyTSRMLS_DC);staticvoidutil_dir_it_move_forward(zend_object_iterator*iterTSRMLS_DC);staticvoidutil_dir_it_rewind(zend_object_iterator*iterTSRMLS_DC);/*iteratorhandlertable*/zend_object_iterator_funcsutil_dir_it_funcs={util_dir_it_dtor,util_dir_it_valid,util_dir_it_current_data,util_dir_it_current_key,util_dir_it_move_forward,util_dir_it_rewind,NULL/*invalidatecurrent*/IteratorsPHPExtensionWriting99Brger,Schlüter/*{{{util_dir_get_iterator*/zend_object_iterator*util_dir_get_iterator(zend_class_entry*ce,zval*object,intby_refTSRMLS_DC){util_dir_it*iterator=emalloc(sizeof(util_dir_it));if(by_ref){zend_error(E_ERROR,"Iteratorinvalidinforeachbyref");}Z_ADDREF_P(object);iterator->intern.
data=(void*)object;iterator->intern.
funcs=&util_dir_it_funcs;iterator->current=NULL;return(zend_object_iterator*)iterator;CreatingtheiteratorAllocateandinitializetheiteratorstructureItisagoodideatoincreasetheoriginalzvalsrefcountPHPExtensionWriting100Brger,Schlüter/*{{{util_dir_it_dtor*/staticvoidutil_dir_it_dtor(zend_object_iterator*iterTSRMLS_DC){util_dir_it*iterator=(util_dir_it*)iter;zval*intern=(zval*)iterator->intern.
data;if(iterator->current){zval_ptr_dtor(&iterator->current);}zval_ptr_dtor(&intern);efree(iterator);DestructingtheiteratorFreeallocatedmemoryandresourcesDon'tforgettoreducerefcountofreferencedobjectPHPExtensionWriting101Brger,Schlüter/*{{{util_dir_it_current*/staticvoidutil_dir_it_current(util_dir_it*iterator,util_dir_object*objectTSRMLS_DC){if(iterator->current){zval_ptr_dtor(&iterator->current);}MAKE_STD_ZVAL(iterator->current);if(object->dirp){ZVAL_STRING(iterator->current,object->entry.
d_name,1);}else{ZVAL_FALSE(iterator->current);}GettingthedataDataisreadonrewind()andnext()callsAzval*isstoredinsidetheiteratorReleasecurrentzvalCreateanewzvalandassignthevaluePHPExtensionWriting102Brger,Schlüter/*{{{util_dir_it_valid*/staticintutil_dir_it_valid(zend_object_iterator*iterTSRMLS_DC){util_dir_it*iterator=(util_dir_it*)iter;util_dir_object*object=(util_dir_object*)zend_object_store_get_object((zval*)iterator->intern.
dataTSRMLS_CC);returnobject->dirp&&object->entry.
d_name[0]!
='\0'SUCCESS:FAILURE;Iteratorvalid()CheckwhetherdataisavailableNote:ReturnSUCCESSorFAILUREnottypicalbooleanPHPExtensionWriting103Brger,Schlüter/*{{{util_dir_it_current_key*/staticintutil_dir_it_current_key(zend_object_iterator*iter,char**str_key,uint*str_key_len,ulong*int_keyTSRMLS_DC){util_dir_it*iterator=(util_dir_it*)iter;zval*intern=(zval*)iterator->intern.
data;util_dir_object*object=(util_dir_object*)zend_object_store_get_object(internTSRMLS_CC);*int_key=object->index;returnHASH_KEY_IS_LONG;Iteratorkey()Thekeymaybeoneof:Integer:HASH_KEY_IS_LONGSetulong*totheintegervalueString:HASH_KEY_IS_STRINGSetuint*tostringlength+1Setchar**tocopyofstring(estr[n]dup)PHPExtensionWriting104Brger,Schlüter/*{{{util_dir_it_current_data*/staticvoidutil_dir_it_current_data(zend_object_iterator*iter,zval***dataTSRMLS_DC){util_dir_it*iterator=(util_dir_it*)iter;*data=&iterator->current;Iteratorcurrent()Thedatawasalreadyfetchedonrewind()/next()PHPExtensionWriting105Brger,Schlüter/*{{{util_dir_it_current_data*/staticvoidutil_dir_it_current_data(zend_object_iterator*iter,zval***dataTSRMLS_DC){util_dir_it*iterator=(util_dir_it*)iter;util_dir_object*object;if(!
iterator->current){object=(util_dir_object*)zend_object_store_get_object((zval*)iterator->intern.
dataTSRMLS_CC);util_dir_it_current(iterator,objectTSRMLS_CC);}*data=&iterator->current;Iteratorcurrent()Thedatawasalreadyfetchedonrewind()/next()AlternativelyResetthecachedcurrent/keyvalueinrewind()/next()CheckthecacheonaccessandreadifnotyetdonePHPExtensionWriting106Brger,Schlüter/*{{{util_dir_it_move_forward*/staticvoidutil_dir_it_move_forward(zend_object_iterator*iterTSRMLS_DC){util_dir_it*iterator=(util_dir_it*)iter;zval*intern=(zval*)iterator->intern.
data;util_dir_object*object=(util_dir_object*)zend_object_store_get_object(internTSRMLS_CC);object->index++;if(!
object->dirp||!
php_stream_readdir(object->dirp,&object->entry)){object->entry.
d_name[0]='\0';}util_dir_it_current(iterator,objectTSRMLS_CC);Iteratornext()MovetonextelementFetchnewcurrentdataPHPExtensionWriting107Brger,Schlüter/*{{{util_dir_it_rewind*/staticvoidutil_dir_it_rewind(zend_object_iterator*iterTSRMLS_DC){util_dir_it*iterator=(util_dir_it*)iter;zval*intern=(zval*)iterator->intern.
data;util_dir_object*object=(util_dir_object*)zend_object_store_get_object(internTSRMLS_CC);object->index=0;if(object->dirp){php_stream_rewinddir(object->dirp);}if(!
object->dirp||!
php_stream_readdir(object->dirp,&object->entry)){object->entry.
d_name[0]='\0';}util_dir_it_current(iterator,objectTSRMLS_CC);Iteratorrewind()RewindtofirstelementFetchfirstcurrentdataPHPExtensionWriting108Brger,SchlüterIteratordrawbacksEitherimplementnativeiteratorsatc-levelOrprovideiteratormethodsandinheritIteratorIfyouwantbothYourPHPmethodscallaspecializedC-LevelhandlerProvideacacheforyourmethodpointersC-LeveliteratorfunctionscheckthiscacheOnamatchcallC-LevelhandlerElsecallthemethodHavetheiteratorstructpartofyourobjectstructUseoffset_of()forpointerconversionPHPExtensionWriting109Brger,SchlüterReferencesThispresentationhttp://talks.
somabo.
deDocumentationandSourcestoPHP5http://php.
nethttp://www.
zend.
com/php/internalsAdvancedPHPProgrammingbyGeorgeSchlossnagleExtendingandEmbeddingPHPbySaraGolemonISBN#0-6723-2704-X

收到几个新商家投稿(HostMem,无忧云,青云互联,TTcloud,亚洲云端,趣米云),一起发布排名不分先后

7月份已经过去了一半,炎热的夏季已经来临了,主机圈也开始了大量的夏季促销攻势,近期收到一些商家投稿信息,提供欧美或者亚洲地区主机产品,价格优惠,这里做一个汇总,方便大家参考,排名不分先后,以邮件顺序,少部分因为促销具有一定的时效性,价格已经恢复故暂未列出。HostMem部落曾经分享过一次Hostmem的信息,这是一家提供动态云和经典云的国人VPS商家,其中动态云硬件按小时计费,流量按需使用;而经典...

HostKvm四月优惠:VPS主机全场八折,香港/美国洛杉矶机房$5.2/月起

HostKvm是一家成立于2013年的国外主机服务商,主要提供基于KVM架构的VPS主机,可选数据中心包括日本、新加坡、韩国、美国、中国香港等多个地区机房,均为国内直连或优化线路,延迟较低,适合建站或者远程办公等。本月商家针对全场VPS主机提供8折优惠码,优惠后美国洛杉矶VPS月付5.2美元起。下面列出几款不同机房VPS主机产品配置信息。套餐:美国US-Plan0CPU:1cores内存:1GB硬...

CYUN(29元/月)美国、香港、台湾、日本、韩国CN2,续费原价

关于CYUN商家在之前有介绍过一次,CYUN是香港蓝米数据有限公司旗下的云计算服务品牌,和蓝米云、蓝米主机等同属该公司。商家主要是为个人开发者用户、中小型、大型企业用户提供一站式核心网络云端部署服务,促使用户云端部署化简为零,轻松快捷运用云计算。目前,CYUN主要运营美国、香港、台湾、日本、韩国CN2线路产品,包括云服务器、站群服务器和独立服务器等。这次看到CYUN夏季优惠活动发布了,依然是熟悉的...

phpempty为你推荐
的人迅雷支持ipaddominavimasios7支持ipadgoogle中国地图谷歌卫星地图中文版下载在哪下??重庆电信宽带管家中国电信10000管家用着怎么样啊??迅雷快鸟迅雷快鸟这种强盗软件不违规吗?ipad上不了网ipad连上家里的无线却不能上网bitchina2015年igem国内大学参加结果altools.u32Authorware 里怎样才能调用flash播放器、播放课件
最新代理服务器 ip查域名 免费申请域名 dns是什么 荷兰服务器 siteground 私人服务器 优key 网站监控 最好看的qq空间 绍兴高防 毫秒英文 howfile 秒杀预告 七夕促销 柚子舍官网 hostloc 新睿云 架设邮件服务器 智能dns解析 更多