
ããã¯ãŸã å¥ã®hello-world-extensionèšäºã§ã¯ãããŸããã åºæ¬ãç解ããã人㯠ã Habréèªäœãšãã·ã¢èªã® RTFGã®äž¡æ¹ã§ç°¡åã«å€ãã®è³æãèŠã€ããããšãã§ããŸãã
åææ¡ä»¶ã販売ãããã³èœãšãç©Žã«é¢ããèšäºã PHPã¯ã»ãšãã©ãªããã»ãšãã©ãCã§ãã
èæ¯
tl; drãèªãããšã«èå³ããªãå Žåã¯ãããã«Implementationã«ã¢ã¯ã»ã¹ã§ããŸãã
é ãããå§ããŸã
ç§ã¯Pythonã奜ãã§ãç¹ã«æ§æã®ããã€ãã®ç¹ã奜ãã§ãã ãããŠãç§ã¯æè¿äž»ã«PHPã§æžããŠããã®ã§ãäœæ¥ããŒã«ããã䟿å©ã§æ©èœçã«ãããã§ãã PHPã¯æè¿ã®ããŒãžã§ã³ã§ã¯éåžžã«ããéçºãããŠããŸãããåããã³ã¬ãŒã¿ãŒããŸã ãããŸããã ãã®ããããã¹ãŠãèªåã®æã§åãæ±ããªããã°ãªããŸããã æåã«ãååãšãã©ã¡ãŒã¿ãŒãã³ã¢é¢æ°ã«æž¡ããšããçµ±äžã®ã¢ã€ãã¢ããããŸããïŒ ç§ã®ã¢ã€ãã¢ã®å¥ã®æ¡åŒµã§ ããŸã ã¢ã€ãã¢ã圢æããŠãã段éã§ããå¿
èŠã«å¿ããŠããã®äœæã«ã€ããŠæžãããšãã§ããŸã ïŒã
é¢æ°ãã³ã¬ãŒã¿ïŒã¡ãœããã¯ãã³ã¬ãŒã·ã§ã³ãšåãã§ããããã以äžã§ã¯èšåããŸããïŒã¯ãåŸè ã®åäœãå€æŽããè¿œå ã®ããžãã¯å±€ã§åŒã³åºããã©ããããããšãã§ããŸãã 宣èšåœ¢åŒã¯ãæçµçã«å ã®é¢æ°ã眮ãæãããã®ãè¿ãå¿ èŠãããã©ãããŒã®ãªã¹ããèšè¿°ããŸãã Pythonæ§æã§ã¯ã 次ã®ããã«ãªããŸã ã
@decomaker(argA, argB, ...) def func(arg1, arg2, ...): # ... # : func = decomaker(argA, argB, ...)(func)
PHPã«ã¯ãã®ãããªå¯èœæ§ã¯ãããŸããã æåã«ããã®æ§æããã®ãŸãŸäœ¿çšããå€æŽããã«è»¢éããããšã«ããŸããïŒåŒã³åºããããšãã«ãã³ã¬ãŒã¿ãŒãã©ã¡ãŒã¿ãŒãæž¡ãããšãé€ããŸãã詳现ã¯ä»¥äžãåç §ïŒã æåã®èšäºã§ã¯ããŸãã«ãã®æ§æã«ã€ããŠèª¬æããŠããŸãã ããããæ§æãã§ãã¯IDEãš2ã€ã®ã³ã¡ã³ããŒã¿ãŒãã£ã³ãã®1ã€ã¯ãç§ãé©ãããŸããã ãã®çµæãæ§æã®ç§»æ€æ§ãåäžããŸãã ãã³ã¬ãŒã¿ã®èª¬æã¯ã1è¡ã®ã³ã¡ã³ãïŒã§èª¬æããå¿ èŠããããŸãã
- ïŒã¯éšåçã«å»æ¢ãããŠããããããã®äœ¿çšã¯éåžžã®//ã/ *ã/ **ãããé¡èã«ãªããŸãã
- åäžè¡ã®ã³ã¡ã³ãã¯åŽ©å£ãããèŠå€±ãã®ãé£ãããªããŸãã
-
çªç¶ãPHP 5.xã§ãã³ã¬ãŒã¿ã衚瀺ãããå¥åŠãªæ§æãæã€ãã®æ¡åŒµæ©èœã®å¿ èŠæ§ããªããªããŸãã
èšè¿°åœ¢åŒã決å®ãããããã³ã¬ãŒã¿èªäœã®å®è£ æ¹æ³ã決å®ããå¿ èŠããããŸãã ãã³ã¬ãŒã¿é¢æ°ã¯ãå ã®ãã³ã¬ãŒã¿ã眮ãæããé¢æ°ãè¿ãå¿ èŠããããŸãã ããã¯ãå¿åé¢æ°ãšã¯ããŒãžã£ãŒã䟿å©ãªå Žæã§ãã
ããã€ãã®PHPã³ãŒã
PHPã§ã¯ããã¡ããããã©ã¡ãŒã¿ãæž¡ãéæ¥çãªé¢æ°åŒã³åºãã¯åé·ã§ããããããåãé€ãããšã¯ã§ããŸããã
<?php function decor($func) { echo "Decorator!\n"; return function () use($func) { return call_user_func_array($func, func_get_args()); }; } function a($v) { var_dump($v); } $b = decor('a'); $b(42); /* : Decorator! int(42) */
PHPã§ã¯ããã¡ããããã©ã¡ãŒã¿ãæž¡ãéæ¥çãªé¢æ°åŒã³åºãã¯åé·ã§ããããããåãé€ãããšã¯ã§ããŸããã
çµæã¯ãèšäºã®åé ã«ããç»åã®æ§æã§ãã
<?php function decor($func) { return function(){} } # @decor function original() { // ... }
ãããŠã Zendã®ã¬ã¯ãµãŒãæžãæããã«ãããååŸããŠãPHPèªäœãåæ§ç¯ããå¿ èŠããªãããã«ããŸãïŒ
å®è£
èšç»ãæºããããã«ã2ã€ã®ãªãã·ã§ã³ããããŸãã
- PHP lexerã«å°éããåã«ãœãŒã¹ã³ãŒããå€æŽããŸãã
- æ¢è£œã®ãªãã³ãŒããå€æŽããŸãããæ§æã¯æ¢åã®ãã®ãšäºææ§ãããã¯ãã§ãã
2çªç®ã®ãªãã·ã§ã³ã¯ãããããçš®é¡ã®ãªãã³ãŒããã£ãã·ã¥ããã³ãªããã£ãã€ã¶ãŒãšã®äºææ§ã«é¢ããŠçããããã®ã§ããã ãã®å Žåããã³ã¬ãŒã¿æ§æã®å ã®ããŒãžã§ã³ïŒïŒã³ã¡ã³ããªãïŒã¯æ©èœããŸããã
æåã®ãªãã·ã§ã³ãéžæãããŸããã
Zendã«ã¯ããœãŒã¹ã³ãŒãåçã®2ã€ã®ãœãŒã¹ããããŸãã
- ã³ãŒãïŒevalã®ã¢ããã°ïŒãå«ãè¡ïŒ zend_eval_string [l] [_ ex] ãæçµçã«ã¯ãã¹ãŠzend_compile_stringã®åŒã³åºãã«ãªããŸãã
- ããŸããŸãªãœãŒã¹ïŒstdinãstreamãªã©ïŒããååŸãããã¡ã€ã«ããã¹ãŠã®ãªãã·ã§ã³ã¯zend_stream_typeåæã«ãªã¹ããããŠããŸãã ãã®å Žåã zend_compile_fileã«èå³ããããŸãã
ã©ã¡ãã®å Žåããç¹å®ã®å®è£ ãæã€é¢æ°ãžã®ãã€ã³ã¿ãŒããããŸãã zend_startupã®åæåãã€ã³ã¿ãŒã調ã¹ããšãæšæºå®è£ ãèŠã€ããããšãã§ããŸãã
- zend_compile_fileã¯compile_fileã«å®è£ ãããŠããŸãã
- zend_compile_string-åæ§ã«æãããªcompile_string ã
ã©ã¡ãã®é¢æ°ãã äœããã®åœ¢åŒã§ãœãŒã¹ã³ãŒããåãå ¥ãã _zend_op_arrayæ§é ã®åœ¢åŒã§ãªãã³ãŒãã®é åãçºè¡ããŸãã æ®å¿µãªãããå®è¡ãããã¿ã¹ã¯ã®é¡äŒŒæ§ã«ããããããããããã®å®è£ ã¯ç°ãªããŸãã ãããã£ãŠãäž¡æ¹ã«åœ±é¿ãäžããŸãã
Zendããã³PHPæ¡åŒµæ©èœã®ãã®ãããªé¢æ°ãã€ã³ã¿ãŒãžã®åœ±é¿ã¯ã¹ããªãŒã ã«çœ®ãããŸãã ããšãã°ãåãzend_compile_fileãZendAcceleratorãšpharã§çœ®ãæããããŸãã ããã¯ããµãŒãããŒãã£ã®æ¡åŒµæ©èœãã«ãŠã³ãããŠããŸããã
代æ¿ãšããŠãã¢ããã°ãå®è£ ãããã€ã³ã¿ãŒã眮ãæããŠãå ã®ãŸãŸã«ããã ãã§ãã ãã¹ãŠããã€ãã®ããã§ãã
次ã®ãããªãã®ãåŸãããŸã
PHP_MINIT_FUNCTION(decorators); PHP_MSHUTDOWN_FUNCTION(decorators); zend_module_entry decorators_module_entry = { // ... decorators_functions, PHP_MINIT(decorators), PHP_MSHUTDOWN(decorators), // ... }; zend_op_array *(*decorators_orig_zend_compile_string)(zval *source_string, char *filename TSRMLS_DC); zend_op_array *(*decorators_orig_zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC); zend_op_array* decorators_zend_compile_string(zval *source_string, char *filename TSRMLS_DC); zend_op_array* decorators_zend_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC); /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(decorators) { decorators_orig_zend_compile_string = zend_compile_string; zend_compile_string = decorators_zend_compile_string; decorators_orig_zend_compile_file = zend_compile_file; zend_compile_file = decorators_zend_compile_file; return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(decorators) { zend_compile_string = decorators_orig_zend_compile_string; zend_compile_file = decorators_orig_zend_compile_file; return SUCCESS; } /* }}} */ zend_op_array* decorators_zend_compile_string(zval *source_string, char *filename TSRMLS_DC) /* {{{ */ { return decorators_orig_zend_compile_string(source_string, filename TSRMLS_CC); } /* }}} */ zend_op_array* decorators_zend_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */ { return decorators_orig_zend_compile_file(file_handle, type TSRMLS_CC); } /* }}} */
ã¢ãžã¥ãŒã«ïŒæ¡åŒµæ©èœïŒãåæåããããšãã«ããã€ã³ã¿ãŒã眮ãæããããäœæ¥ã®å®äºæã«ãã¹ãŠãè¿ãããšãå¿ããŸããã§ããã 眮ãæããããé¢æ°ã§çŽæ¥ãå ã®å®è£ ãåŒã³åºããŸãã
ã¢ãžã¥ãŒã«ã®åæåäžã«ãã¹ãŠãå®è¡ã§ããããã§ã¯ãããŸãããããã®å Žåã¯ããã§ååã§ãã
ãããŠãcompile_stringïŒå ¥åè¡ãå ¥åã«æ¥ãïŒã§ãã¹ãŠãå€ããå°ãªããæ確ãªå Žåãcompile_fileã§ã¯ãã¹ãŠãããã»ã©ãã©è²ã§ã¯ãªãããœãŒã¹ããªãããœãŒã¹ã®èª¬æã®ã¿ãzend_file_handleã«ãããŸãã ããã«ãç°ãªãã±ãŒã¹ã§ã¯ãç°ãªããã£ãŒã«ãã®ã»ããã䜿çšãããŸãã
ãœãŒã¹ã®çŽæ¥èªã¿åãã¯ããªãé ããŸã§åãŸã£ãŠããŸã
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) { // ... open_file_for_scanning(file_handle TSRMLS_CC) // ... } ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC) { // ... zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) // ... }
ãããŠãããã§æãèå³æ·±ãã®ã¯ããœãŒã¹ã³ãŒãã®å ¥åã®ãã¹ãŠã®ãœãŒã¹ãçµ±åã ãèªã¿åããããã¡ãŒãšãã®ãµã€ãºãåºåã§åºåããé¢æ°zend_stream_fixupã§ãã ãããå¿ èŠãªããã«èŠããŸãããzend_stream_fixupãšopen_file_for_scanningã®åäœã«åœ±é¿ãäžããããšã¯ã§ããŸãããcompile_fileãå¶åŸ¡ããã ãã§ãã 誰ãããããã®é¢æ°ãšãã®ãã¹ãŠã®äŸåé¢ä¿ãèªåèªèº«ã«ã³ããŒããŸãããããããç°¡åã«ããŸãã zend_stream_fixupã®ãœãŒã¹ã³ãŒããèŠããšããã¹ãŠã®ã¿ã€ããæçµçã«åäžã®ZEND_HANDLE_MAPPEDã«çž®å°ãããŠããããšãããããŸãããã®ãã¡ã€ã«ã«ã¯ãfile_handle-> handle.stream.mmap.bufããã³file_handle-> handle.stream.mmap.lenã«ãããããœãŒã¹ã³ãŒããšãã®é·ããå«ãŸããŠããŸãã ããã«ããã®ããŒã¿åãfile_handleã§æ¢ã«æå®ãããŠããå Žåãå®éã«ã¯äœãå€æŽããå¿ èŠã¯ãªãããã¹ãŠããã®ãŸãŸè¿ãããŸãã
compile_fileïŒïŒzend_file_handle * file_handleã«ãã¹ãŠã®ãã£ãŒã«ãã«æ£ããå€ãæå®ãããã©ãŒãããZEND_HANDLE_MAPPEDã§æ¢ã«æž¡ããšãcompile_fileã¯ããããã®ãŸãŸåãå ¥ããŸãã ãããŠãcompile_fileãåŒã³åºãåã«ããäžåºŠzend_stream_fixupïŒZend APIé¢æ°ã§ããã亀æå¯èœãªãã€ã³ã¿ãŒã§ã¯ãªãïŒãåŒã³åºãããšã§ãããè¡ãããšãã§ããŸãã ãã®åŸãopen_file_for_scanningå ã§ååŒã³åºãããŠããäœãå€ãããŸããã
ãè©Šããã ãã
zend_op_array* decorators_zend_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */ { char *buf; size_t size; if (zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) == FAILURE) { return NULL; } // file_handle ZEND_HANDLE_MAPPED return decorators_orig_zend_compile_file(file_handle, type TSRMLS_CC); } /* }}} */
ããããã ããã«ãfile_handle-> handle.stream.mmap.buf / lenã«ã¯ãPHPãååŸãããœãŒã¹ïŒstdinãfdãinclude httpã¹ããªãŒã ïŒããããŸã...å€æŽãããããŒãžã§ã³ã®ã³ãŒããããã«é 眮ããå ã®zend_compile_fileãåŒã³åºããŸãã
decorators_preprocessorïŒïŒã®ä»çµã¿ã説æããŸãããæååã®æãããªåä¿¡ãããªããã»ããµãžã®éä¿¡ãçµæã®æååã®æ»ãã§ãã 以äžã«ããã®é¢æ°ããã®ã³ãŒãã®æçããããŸãã
ããªããã»ããµèªäœãæ€èšããå¿ èŠããããŸãã
ç°ãªããœãŒã¹ããŒã¿ãåäžã®é¢æ°ã«æž¡ã
void preprocessor(zval *source_zv, zval *return_value TSRMLS_DC) { // source_zv return_value } /* {{{ DECORS_CALL_PREPROCESS */ #define DECORS_CALL_PREPROCESS(result_zv, buf, len) \ do { \ zval *source_zv; \ ALLOC_INIT_ZVAL(result_zv); \ ALLOC_INIT_ZVAL(source_zv); \ ZVAL_STRINGL(source_zv, (buf), (len), 1); \ preprocessor(source_zv, result_zv TSRMLS_CC); \ zval_dtor(source_zv); \ FREE_ZVAL(source_zv); \ } while (0); \ /* }}} */ /* {{{ proto string decorators_preprocessor(string $code) */ PHP_FUNCTION(decorators_preprocessor) { char *source; int source_len; zval *result; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) { return; } DECORS_CALL_PREPROCESS(result, source, source_len); // ... } /* }}} */ zend_op_array* decorators_zend_compile_string(zval *source_string, char *filename TSRMLS_DC) /* {{{ */ { zval *result; DECORS_CALL_PREPROCESS(result, Z_STRVAL_P(source_string), Z_STRLEN_P(source_string)); // ... } /* }}} */ zend_op_array* decorators_zend_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */ { // ... zval *result; DECORS_CALL_PREPROCESS(result, file_handle->handle.stream.mmap.buf, file_handle->handle.stream.mmap.len); // ... } /* }}} */
æ€çŽ¢ããŠããçŽããŸãããïŒ
ããªããã»ããµã®ã¿ã¹ã¯ã¯ããã³ã¬ãŒã¿ã®èª¬æãèŠã€ããŠããã³ã¬ãŒã¿ã圱é¿ããé¢æ°ã®ã³ãŒããå€æŽããããšã§ãã ãã®ããã«ã¯ããœãŒã¹ããã¹ãã®ããŒã¯ã³ã䜿çšããã®ãæé©ã§ãã è»èŒªãåçºæããªãããã«ããã€ãã£ãã®Zendã®lex_scanåå¥ã¹ãã£ããŒã䜿çšãããŸãã ããã®äŸã¯ã token_get_allå ã§åŒã³åºãããtoken_get_allããã³tokenizeã®å®è£ ã§ç¬èªã®ç®çã«äœ¿çšã§ããŸãã
- ã³ãŒããæ©èœããã¹ãã£ããŒã®çŸåšã®ç°å¢ãä¿åããŸãã
zend_lex_state original_lex_state;
zend_save_lexical_stateïŒïŒoriginal_lex_state TSRMLS_CCïŒ;
- 解æçšã®ãœãŒã¹è¡ãæºåããŸãã
zend_prepare_string_for_scanningïŒïŒsource_zã "" TSRMLS_CCïŒ
- ã¬ã¯ãµãŒã®åæç¶æ
ãèšå®ããŸãïŒãã¹ãŠã®ãªãã·ã§ã³ã¯ããã«ãããŸã ïŒã
LANG_SCNGïŒyy_stateïŒ= yycST_IN_SCRIPTING;
token_get_allãšã¯ç°ãªããPHPã³ãŒãã¯ãã§ã«è§£æãããŠãããããéå§ã¿ã°ã¯å¿ èŠãããŸããã ãããã£ãŠãåæç¶æ ã¯yycINITIALã§ã¯ãªããyycST_IN_SCRIPTINGã§ãã
- ã«ãŒãã§ã¯ããœãŒã¹æååã®ãã¹ãŠã®ããŒã¯ã³ãååŸããŸãã
zval token_zv;
int token_type;
whileïŒtoken_type = lex_scanïŒïŒtoken_zv TSRMLS_CCïŒïŒ{
// ...
}
token_type-ããŒã¯ã³ã¿ã€ãïŒ
- <256-1æåã®ããŒã¯ã³ã®æåã³ãŒãã
- > = 256ã¯å®æ°T_ *ã®å€ã§ãã token_typeã®ã¹ããªã³ã°èšè¿°ã¯ãPHP_FUNCTIONïŒtoken_nameïŒ/ get_token_type_nameãä»ããŠååŸã§ããŸãã
token_zvã«ã¯ãããŒã¯ã³ã®æå³ãå«ãŸããŠããŸãã ãã ãã代ããã«ãçŸåšã®ããŒã¯ã³ã®æåã®ãã€ãã®ã¢ãã¬ã¹ãšãã®é·ããããããæ ŒçŽããzend_lex_stateæ§é äœã®yy_textãã£ãŒã«ããšyy_lengãã£ãŒã«ãã䜿çšã§ããŸãã Zendãšåæ§ããããã®ãã£ãŒã«ããžã®ã¢ã¯ã»ã¹ã¯ã察å¿ãããã¯ããä»ããŠå®è£ ãããŸãã
#define zendtext LANG_SCNGïŒyy_textïŒ
#define zendleng LANG_SCNGïŒyy_lengïŒ
ããã§ãchar * zendtextãšunsigned int zendlengã䜿çšããŸãã
ã¡ã¢ãªãªãŒã¯ãåé¿ããã«ã¯ãtoken_zvã®å€ãå ã®ãããã¡ãããã®ãŸãŸäœ¿çšãããããã¡ã¢ãªãå²ãåœãŠããããããããšãèæ ®ããå¿ èŠããããŸãã 解æŸããå¿ èŠããããŸãã èå³ã®ããæ¹ã¯lex_scanïŒïŒã³ãŒããèŠãŠãtoken_get_allããå¿ èŠãªããžãã¯ãåãåºãããšãã§ããŸãã
- ã³ãŒããæ©èœããã¹ãã£ããŒã®ç°å¢ã埩å
ããŸãã
zend_restore_lexical_stateïŒïŒoriginal_lex_state TSRMLS_CCïŒ;
以äžã§ããœãŒã¹ã³ãŒãã®åå¥è§£æãã§ããŸããã ãããã解æã®åé¡ãããã«åŒ·èª¿ããããšæããŸãã
PHPããšã©ãŒã解æããå Žåããã³ãã©ãŒã¯ãšã©ãŒãŸãã¯äŸå€ãçæããããã¹ãå ã®ãã¡ã€ã«åãšè¡çªå·ã¯_zend_compiler_globalsç¶æ ããååŸãããŸãã ããšãã°ããã¡ã€ã«åã¯ãcompiled_filenameãã£ãŒã«ãããååŸãããŸãã zend_prepare_string_for_scanningïŒïŒãåŒã³åºããããšãã«èšå®ãããŸãã ãããŠãããã¯zend_errorå ã§äœ¿çšãããŸã ïŒããããçš®é¡ã®E_ *ãšã©ãŒãçæããããã«äœ¿çšãããŸããE_PARSEãçæããããã«ãã®æ¡åŒµæ©èœã§ã䜿çšãããŸãïŒã ãã ããzend_errorïŒïŒã®compile_filenameã¯ãZendãã³ã³ãã€ã«ç¶æ ïŒzend_bool in_compilationããã¹ãŠåã_zend_compiler_globalsïŒã®å Žåã«ã®ã¿äœ¿çšãããŸãã ãœãŒã¹ã解æãããšãããèªäœã¯ã¢ã¯ãã£ãã«ãªããŸããã
解æããåã«ããã³ã³ãã€ã«ãã«åãæ¿ããŸãã
zend_bool original_in_compilation = CGïŒin_compilationïŒ;
CGïŒin_compilationïŒ= 1;
ãããŠæåŸã«ãã¹ãŠãè¿ããŸãïŒ
CGïŒin_compilationïŒ= original_in_compilation;
ããã§ãæ£ãããã¡ã€ã«åãzend_prepare_string_for_scanningã«æž¡ããšãçºçããå¯èœæ§ã®ãããšã©ãŒãããã«ãããããããªããŸãã çŸåšã®ãã¡ã€ã«åã¯zend_get_compiled_filenameïŒïŒã§ååŸã§ããŸãããããã¯NULLãè¿ãããšãã§ããããããPHPïŒNULLãzend_prepare_string_for_scanningã«æž¡ãããå ŽåïŒã¯segfaultã«åé¡ãããŸãã
decorators_preprocessorããã³decorators_zend_compile_fileã«æ£ãããã¡ã€ã«åãèšå®ããããã«æ®ã£ãŠããŸã
decorators_zend_compile_stringã§ã¯ããã¡ã€ã«åã¯ãã§ã«ããã£ãŠããŸãã
PHP_FUNCTION(decorators_preprocessor) { // ... char *prev_filename = zend_get_compiled_filename(TSRMLS_CC) ? zend_get_compiled_filename(TSRMLS_CC) : ""; zend_set_compiled_filename("-" TSRMLS_CC); DECORS_CALL_PREPROCESS(result, source, source_len); zend_set_compiled_filename(prev_filename TSRMLS_CC); // ... } zend_op_array* decorators_zend_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */ { // ... char *prev_filename = zend_get_compiled_filename(TSRMLS_CC) ? zend_get_compiled_filename(TSRMLS_CC) : ""; const char* filename = (file_handle->opened_path) ? file_handle->opened_path : file_handle->filename; zend_set_compiled_filename(filename TSRMLS_CC); zval *result; DECORS_CALL_PREPROCESS(result, file_handle->handle.stream.mmap.buf, file_handle->handle.stream.mmap.len); zend_set_compiled_filename(prev_filename TSRMLS_CC); // ... }
decorators_zend_compile_stringã§ã¯ããã¡ã€ã«åã¯ãã§ã«ããã£ãŠããŸãã
ãœãŒã¹ã³ãŒãã®å€æŽ
ååŠçã«å¿ èŠãªãã¹ãŠãåãåã£ãåŸããããçæããããšã¯æ®ã£ãŠããŸãã ãã£ã³ã¯ïŒããŒã¯ã³ïŒã§æ§æãããããã¹ããçµæã®ããã¹ãã«å€æããã¿ã¹ã¯ã¯ãæååãæ¥çããäœæ¥ã掻çºã«è¡ãããŠãããããCã§ã¯ããã»ã©åçŽã§ã¯ãªããããããŸããã ãã ãã / PHP / ext / standard / php_smart_str.hã«ã¯ãéåžžã«åœ¹ç«ã€ã¹ããŒãã©ã€ã³ã®å®è£ ããããŸãã
ãŸããªã
smart_str str = {0}; smart_str str2 = {0}; smart_str_appendc(&str, '!'); smart_str_appendl(&str, "hello", 5); smart_str_append(&str, &str2); smart_str_append_long(&str, 42); // .. // size_t str.len char* str.c // : smart_str_free(&str);
ããŒã¯ã³ã®è§£æã®ãµã€ã¯ã«ã§ãããŒã¯ã³ïŒzendtextãzendlengïŒã®çµæã®æååãæ¥çããŸããããã§ãèªåã§å€æŽ/è¿œå ããå¿ èŠããããŸãã çŽæ¥ããã³ã¬ãŒã¿ã眮ãæããããã®ã¢ã«ãŽãªãºã ãIMHOã¯ããã»ã©èå³æ·±ããã®ã§ã¯ãããŸããã èå³æ·±ãå¯èœæ§ã®ããç¹ãããã¿ã€ãT_COMMENTã®ããŒã¯ã³ããã³ã¬ãŒã¿ã®èª¬æã«äŒŒãŠããããšã確èªããŸããèŠåæ§ã®ç¢ºèªã¯^ ^ [[\ t] * @ 'ïŒæ£èŠè¡šçŸã®ãªãåçŽãªã«ãŒãã䜿çšïŒããã³ã¢ãã¬ã¹' @ 'ãè¿ãããŸãã
æåŸã«å°ããªPHP
ãã³ã¬ãŒã¿ãåŠçãããšããè£ é£Ÿãããé¢æ°ã®ãœãŒã¹ã³ãŒãã¯ãããã«å€åããŸããé¢æ°ã®æ¬äœã¯å¿åé¢æ°ã§ã©ããããããã©ã¡ãŒã¿ã«ãã£ãŠæãè¿ããã³ã¬ãŒã¿ã«æž¡ãããŸãã ã€ãŸã ã³ãŒãçš
// comment @a(A) @b @c(C, D) /** * yet another comment */ function x(X) { Y }
ååŠçã®çµæã次ã®ã³ãŒããååŸãããŸãã
// comment /** * yet another comment */ function x(X) { return call_user_func_array(a(b(c(function(X) { Y }, C, D)), A), func_get_args());}
AãCãDãXãšã¯ããã®ãŸãŸã³ããŒãããä»»æã®ã³ãŒããæå³ããŸãã
ããã«ããã次ã®çµæãçããŸãã
- ãã³ã¬ãŒãããé¢æ°ãããã©ã«ãå€ãæã€ãã©ã¡ãŒã¿ãŒã§å®£èšãããŠããå Žåãå¿åé¢æ°ã§ã¯ãã¹ãŠãåãã«ãªããŸãã
é¢æ°fooïŒ$ aã$ b = 42ã$ c =é åïŒ100ã500ïŒïŒ
{...
=>
é¢æ°fooïŒ$ aã$ b = 42ã$ c =é åïŒ100ã500ïŒïŒ
{return call_user_func_arrayïŒ...ïŒfunctionïŒ$ aã$ b = 42ã$ c = arrayïŒ100ã500ïŒïŒ{...
- ãã³ã¬ãŒã¿åã®èª¬æã«ãšã©ãŒãããå Žåããšã©ãŒã説æãããšãã®ã³ãŒãè¡ã¯ãæ¬æãéãé¢æ°ã{ããå«ãè¡ã«ãªããŸãã åæ§ã«ããã³ã¬ãŒã¿ãŒãã©ã¡ãŒã¿ãŒã«ã€ããŠã¯ãé¢æ° '}'ãæ¬æãéããè¡ã«ãããŸãã
- ãã³ã¬ãŒã¿ãã©ã¡ãŒã¿ã¯ãè£ é£Ÿãããé¢æ°ã®å€æ°åã«èšå®ã§ããŸãã ãã©ã¡ãŒã¿ã®èªã¿åã/æžã蟌ã¿å¶åŸ¡ãå€æããŸãã
- ãªããªã func_get_argsïŒïŒã䜿çšããŠãã©ã¡ãŒã¿ãŒãæž¡ããšãè£ é£Ÿãããé¢æ°ãžã®åç §ã«ãããã©ã¡ãŒã¿ãŒã®åãæž¡ãã¯çŸåšæ©èœããŸããã
ãŸããããã ãã§ãã æ¬åœã«ãããŸã§èªãã ããããããããããã£ããšæããŸãã
ãã®èšäºã§ã¯githubãžã®ãªã³ã¯ãæäŸããŸãã