åºåãããã¡ãŒãšã¯äœã§ããïŒ
PHPã®åºåã¹ããªãŒã ã«ã¯ãéåžžãéçºè ã衚瀺ããå¿ èŠã®ããããã¹ã圢åŒã®ãã€ããå«ãŸããŠããŸãã ã»ãšãã©ã®å Žåããã®ããã«echoãŸãã¯printfïŒïŒã³ã³ã¹ãã©ã¯ãã䜿çšãããŸãã ãŸããäœããåºåããé¢æ°ã¯PHPãã¡ã€ã³ã®BVã䜿çšããããšãç解ããå¿ èŠããããŸãã PHPã®æ¡åŒµæ©èœã«ã€ããŠèª¬æãããšãã¢ããã¹ããªãŒã BVããã€ãã¹ããŠãSAPIã«çŽæ¥æžã蟌ãé¢æ°ã«ã¢ã¯ã»ã¹ã§ããŸãã C APIã¯lxr.php.net/xref/PHP_5_5/main/php_output.hã«ææžåãããŠããŸããããšãã°ãããã©ã«ãã®ãããã¡ãŒãµã€ãºãªã©ãå€ãã®æ å ±ãããããåéã§ããŸãã
2çªç®ã®éèŠãªãã€ã³ãïŒBVã¬ã€ã€ãŒã¯ãåºåããŒã¿ããããã¡ãªã³ã°ãããå¯äžã®ã¬ã€ã€ãŒã§ã¯ãããŸããã
3çªç®ïŒäœ¿çšããŠããSAPIïŒwebãŸãã¯cliïŒã«å¿ããŠãBVã¬ã€ã€ãŒã®åäœã¯ç°ãªããŸãã
以äžã¯ãäžèšã®ãã¹ãŠãç解ããã®ã«åœ¹ç«ã€å³ã§ãã
![](https://habrastorage.org/files/4be/49c/042/4be49c0423d1429fad7f68ebb6311e3a.jpg)
ããã§ãPHPã¯3ã€ã®è«çãããã¡ãªã³ã°ã¬ã€ã€ãŒã䜿çšããŠåºåããŒã¿ãå¶åŸ¡ããŠããããšãããããŸãã ãããã®2ã€ã¯åããåºåãããã¡ãŒãã«å±ãã3ã€ç®ã¯SAPIã«å±ããŸãã åºåã¹ããªãŒã ãPHPãã¡ã€ã³ãé¢ããŠã¢ãŒããã¯ãã£ã®äžäœã¬ãã«ã«å°éãããšãéäžã§æ°ãããããã¡ãŒã衚瀺ãããå ŽåããããŸããã¿ãŒããã«ãããã¡ãŒãFastCGIãããã¡ãŒãWebãµãŒããŒãããã¡ãŒããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãããã¡ãŒãTCP / IPã¹ã¿ãã¯ãããã¡ãŒã§ãã ãããå¿ããªãã§ãã ããã ãã®èšäºã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯PHPã«ã€ããŠã®ã¿èª¬æããŸãããæäžå±€ãšãŠãŒã¶ãŒã«åããéäžã®ã¹ã¿ãã¯ã«ã¯ãŸã å€ãã®ãœãããŠã§ã¢ããŒã«ããããŸãã
SAPI CLIã«é¢ããéèŠãªæ³šæïŒ output_bufferingãã©ã¡ãŒã¿ãŒiniã0ã«èšå®ããããšã«ãããPHPã®ããã©ã«ãåºåãããã¡ãŒãç¡å¹ã«ããŸãããããã£ãŠãCLIã§ob_ïŒïŒé¢æ°ãæåã§èšè¿°ãããŸã§ãããã©ã«ãã§ãã¹ãŠã®åºåã¯SAPIã¬ã€ã€ãŒã«çŽæ¥éãããŸãã ããã«ãCLIã§ã¯implicit_flushãã©ã¡ãŒã¿ãŒã«å€1ãæé»çã«æå®ãããŠããŸããéçºè ã¯ãã®ãã©ã¡ãŒã¿ãŒã®æ¬è³ªãåžžã«èª€è§£ããŠããŸãããã³ãŒãã§ã¯å®å šã«æ確ã§ãããšè¿°ã¹ãŠããŸãã ã€ãŸããCLI SAPIã䜿çšããŠåºåçšã®ããŒã¿ãæžã蟌ããã³ã«ããããã¯ããã«äžäœã¬ãã«ã«éä¿¡ãããããã§æšæºåºåãšããŠæžã蟌ãŸãããªã»ãããããŸãã
æšæºPHPåºåãããã¡ãªã³ã°ã¬ã€ã€ãŒ
CLIã§ã¯ãªããããšãã°PHP-FPMã®ãããªSAPIã䜿çšããå Žåããããã¡ã«é¢é£ããiniã®3ã€ã®ãã©ã¡ãŒã¿ãŒãè©Šãããšãã§ããŸãã
- output_buffering
- implicit_flush
- output_handler
ããããini_setïŒïŒã䜿çšããŠããPHPãã¹ã¯ãªãããå®è¡ããåã«PHPã®èµ·åæã«èªã¿èŸŒãŸãããããå¹æã¯ãããŸããã ãããã®ãã©ã¡ãŒã¿ã®ããããã§ini_setïŒïŒã䜿çšãããšãå€ãå€æŽãããŸãããã©ãã§ã䜿çšãããŸããã é ããã-BIã¬ã€ã€ãŒã¯ãã§ã«å®è¡ãããŠãããã¢ã¯ãã£ãã§ãã ãããã®ãã©ã¡ãŒã¿ãŒãå€æŽããã«ã¯ãphp.iniãç·šéããããPHPãã€ããªã«-dã¹ã€ãããé©çšããŸãã
ããã©ã«ãã§ã¯ãPHPã«å梱ãããŠããphp.iniã output_buffering㯠ã4096ãïŒãã€ãïŒã«èšå®ãããŠããŸãã php.iniã䜿çšããªãå ŽåïŒãŸãã¯ânã¹ã€ãããæå®ããŠPHPãå®è¡ããå ŽåïŒãããã©ã«ãå€ã¯ã0ããã€ãŸãç¡å¹ã«ãªããŸãã ããŒãã³ãŒããããªã³ãã«èšå®ãããŠããå Žåãåºåãããã¡ã®æšæºãµã€ãºïŒ16 KBïŒãå²ãåœãŠãããŸãã
ããããæ¢ã«æšæž¬ããããã«ãWebç°å¢ã§åºåã«ãããã¡ãŒã䜿çšãããšãããã©ãŒãã³ã¹ã«æçãªå¹æããããŸãã æåã®4 KBã§ååã§ããããã¯ãPHPãåºç€ãšãªãSAPIã¬ã€ã€ãŒãšã®å¯Ÿè©±ãéå§ãããŸã§ãæ倧4096ã®ASCIIæåãæžã蟌ãããšãã§ããããã§ãã Webã§ã¯ããã€ãåäœã§ããŒã¿ãéä¿¡ããŠããããã©ãŒãã³ã¹ã¯åäžããŸããã ãµãŒããŒããã¹ãŠã®ã³ã³ãã³ãããŸãšããŠéä¿¡ãããããŸãšããŠéä¿¡ããæ¹ãã¯ããã«åªããŠããŸãã ã¬ãã«ãããŒã¿ã亀æããé »åºŠãå°ãªãã»ã©ãããã©ãŒãã³ã¹ãåäžããŸãã ãããã£ãŠãå¿ ãåºåãããã¡ã䜿çšããŠãã ããã PHPã¯ãªã¯ãšã¹ãã®æåŸã«ãã®å 容ãéä¿¡ããŸãããã®ããã«äœãããå¿ èŠã¯ãããŸããã
åã®ç« ã§ãCLIã®ã³ã³ããã¹ãã§implicit_flushã«ã€ããŠèšåããŸããã ä»ã®SAPIã®å Žåã implicit_flushã¯æåã¯ç¡å¹ã«ãªã£ãŠããŸãã SAPIãžã®æžã蟌ã¿çŽåŸã«SAPIã®ãªã»ãããæè¿ããå¯èœæ§ã¯äœããããããã¯è¯ãããšã§ãã FastCGIãããã³ã«ã®å Žåããªã»ããã¯ãæžã蟌ã¿ã®ãã³ã«ãã±ãããçµäºããŠéä¿¡ããããšãšæ¯èŒã§ããŸãã ãã ããæåã«FastCGIãããã¡ãŒãå®å šã«ãã£ã±ãã«ããŠããããã±ãããéä¿¡ããããšããå§ãããŸãã SAPIãããã¡ãŒãæåã§ãªã»ããããå¿ èŠãããå Žåã¯ãããã«PHPé¢æ°flushïŒïŒã䜿çšããŸãã åè¿°ã®ããã«ãåã¬ã³ãŒãã®åŸã«ââãªã»ããããã«ã¯ãphp.iniã§implicit_flushãã©ã¡ãŒã¿ãŒã䜿çšã§ããŸãã ãŸãã¯ãPHPé¢æ°ob_implicit_flushïŒïŒã® 1åã®åŒã³åºãã
ãããã¡ãŒã®åºååã«ãã³ãŒã«ããã¯output_handlerããããã¡ãŒã®ã³ã³ãã³ãã«é©çšã§ããŸãã äžè¬ã«ãPHPæ¡åŒµæ©èœã®ãããã§ãå€ãã®ã³ãŒã«ããã¯ã䜿çšã§ããŸãïŒãŠãŒã¶ãŒã¯ããããäœæããããšãã§ããŸããããã«ã€ããŠã¯ã次ã®ç« ã§èª¬æããŸãïŒã
- ob_gzhandlerïŒext / zlibã«ããåºåã®å§çž®
- mb_output_handlerïŒext / mbstringã§æåãšã³ã³ãŒãã£ã³ã°ãå€æããŸã
- ob_iconv_handlerïŒext / iconvã§æåãšã³ã³ãŒãã£ã³ã°ãå€æããŸã
- ob_tidyhandlerïŒHTMLåºåãext / tidyã§ãã©ãã·ã¥
- ob_ [inflate / deflate] _handlerïŒext / httpã§åºåãå§çž®ããŸã
- ob_etaghandlerïŒext / httpã䜿çšããŠETagããããŒãèªåçæ
䜿çšã§ããã³ãŒã«ããã¯ã¯1ã€ã ãã§ããã³ãŒã«ããã¯ã¯ããããã¡ãŒã®ã³ã³ãã³ããåãåããåºåã®æçšãªå€æãè¡ããŸããããã¯æå ±ã§ãã ãµãŒããŒããŠãŒã¶ãŒã«éä¿¡ããWebãµãŒããŒã«PHPãéä¿¡ããããŒã¿ãåæããã«ã¯ãã³ãŒã«ããã¯ãšåºåãããã¡ãŒã䜿çšãããšäŸ¿å©ã§ãã ãšããã§ããçµè«ããšã¯ãèŠåºããšæ¬æã®äž¡æ¹ãæå³ããŸãã HTTPããããŒãåºåãããã¡å±€ã®äžéšã§ãã
ããã£ãšããããŒ
åºåãããã¡ã䜿çšããå ŽåïŒã«ã¹ã¿ã ã§ãããæšæºã®ãããã¡ã§ãããã¯é¢ä¿ãããŸããïŒãHTTPããããŒãšã³ã³ãã³ãã奜ããªããã«éä¿¡ã§ããŸãã ã©ã®ãããã³ã«ã§ãæåã«ããããŒãéä¿¡ãã次ã«æ¬æãéä¿¡ããå¿ èŠããããŸãããBVã¬ã€ã€ãŒã䜿çšããå Žåã¯PHPãéä¿¡ããŸãã ããããŒïŒ headerïŒïŒãsetcookieïŒïŒãsession_startïŒïŒ ïŒã§åäœããPHPé¢æ°ã¯ãå®éã«ã¯å éšé¢æ°sapi_header_opïŒïŒã䜿çšããŸããããã¯ãåã«ããããŒãããã¡ãŒãåããŸãã ãã®åŸãããšãã°printfïŒïŒã䜿çšããŠåºåããŒã¿ãæžã蟌ããšã察å¿ããåºåãããã¡ãŒã®1ã€ã«æžã蟌ãŸããŸãã ãããŠãæåã«PHPãããã¡ãéä¿¡ããŠããé
ããããŒãéä¿¡ããŠãããããã£ã®ã¿ãéä¿¡ããŸãã PHPã®ãã®æžå¿µãæ°ã«å ¥ããªãå Žåã¯ãBVã¬ã€ã€ãŒãå®å šã«ç¡å¹ã«ããå¿ èŠããããŸãã
ã«ã¹ã¿ã åºåãããã¡ãŒ
ãããã©ã®ããã«æ©èœããäœãã§ãããã®äŸãèŠãŠã¿ãŸãããã æšæºã®PHPãããã¡ãªã³ã°ã¬ã€ã€ãŒã䜿çšããå ŽåãCLIã¯ã¬ã€ã€ãŒãšããŠç¡å¹ã«ãªã£ãŠãããã䜿çšã§ããªãããšã«æ³šæããŠãã ããã
以äžã¯ãå éšSAPI WebãµãŒããŒã䜿çšããŠæšæºã®PHPã¬ã€ã€ãŒãæäœããäŸã§ãã
/* : php -doutput_buffering=32 -dimplicit_flush=1 -S127.0.0.1:8080 -t/var/www */ echo str_repeat('a', 31); sleep(3); echo 'b'; sleep(3); echo 'c';
æšæºã®32ãã€ãã®åºåãããã¡ãŒã§PHPãéå§ãããã®åŸãå®è¡é 延ããªã³ã«ãªããŸã§ããã«31ãã€ããæžã蟌ã¿ãŸããã äœãéä¿¡ãããªãéããç»é¢ã¯é»ã§ãã ãã®åŸã sleepïŒïŒã¢ã¯ã·ã§ã³ãçµäºããå¥ã®ãã€ããæžã蟌ãããšã§ããããã¡ãŒãå®å šã«ãã£ã±ãã«ãªããŸãã ãã®åŸã implicit_flushã®å€ã1ã§ããããã圌ã¯ããã«SAPIã¬ã€ã€ãŒã®ãããã¡ãŒã«èªåèªèº«ããã©ãã·ã¥ããåºåã«èªåèªèº«ããã©ãã·ã¥ããŸãã å®äºãããšã空ã®31ãã€ãã®ãããã¡ãŒã1ãã€ãã§åãããããã®åŸPHPãçµäºããŠãããã¡ãŒããã©ãã·ã¥ããŸãã ã§ç»é¢ã«è¡šç€ºãããŸãã
ããã¯ãobé¢æ°ãåŒã³åºããªãæšæºã®PHPãããã¡ãŒã®åäœã§ãã ãããæšæºãããã¡ãŒã§ããããšãã€ãŸãããã§ã«äœ¿çšå¯èœã§ããããšãå¿ããªãã§ãã ããïŒCLIã䜿çšããããšã¯ã§ããŸããïŒã
ob_startïŒïŒã䜿çšãããšãã¡ã¢ãªããªããªããŸã§ã«ã¹ã¿ã ãããã¡ãå¿ èŠãªæ°ã ãå®è¡ã§ããŸãã åãããã¡ã¯åã®ãããã¡ã®åŸãã«é 眮ãããããã«æ¬¡ã®ãããã¡ã«ãã©ãã·ã¥ãããŸããããã«ãããåŸã ã«ãªãŒããŒãããŒãçºçããŸãã
ob_start(function($ctc) { static $a = 0; return $a++ . '- ' . $ctc . "\n";}, 10); ob_start(function($ctc) { return ucfirst($ctc); }, 3); echo "fo"; sleep(2); echo 'o'; sleep(2); echo "barbazz"; sleep(2); echo "hello"; /* 0- FooBarbazz\n 1- Hello\n */
åºåãããã¡è£ 眮
åè¿°ããããã«ãããŒãžã§ã³5.4以éãåºåãããã¡ãªã³ã°ã¡ã«ããºã ã¯å®å šã«æžãçŽãããŸããã ãã以åã¯ãã³ãŒãã¯éåžžã«ä¹±éã§ãå€ãã®ããšãç°¡åã§ã¯ãªããå€ãã®å Žåãã°ãçºçããŠããŸããã 詳现ã«ã€ããŠã¯ã ãã¡ããã芧ãã ãã ã æ°ããã³ãŒãããŒã¹ã¯ãã¯ããã«ãããã§ãæŽçãããŠãããæ°ããæ©èœãç»å ŽããŠããŸãã 確ãã«ãããŒãžã§ã³5.3ãšã®äºææ§ã¯éšåçã«ããæäŸãããŠããŸããã
ããããæã楜ããé©æ°ã®1ã€ã¯ãæ¡åŒµæ©èœããä»ã®æ¡åŒµæ©èœã®ã³ãŒã«ããã¯ãšç«¶åããã³ãŒã«ããã¯ãšåºåãããã¡ãŒã宣èšã§ããããã«ãªã£ãããšã§ãã 以åã¯ãä»ã®æ¡åŒµæ©èœãã³ãŒã«ããã¯ã宣èšã§ããç¶æ³ãå®å šã«ç®¡çããããšã¯äžå¯èœã§ããã
ããŒã¿ã倧æåã«å€æããã³ãŒã«ããã¯ãç»é²ããæ¹æ³ã瀺ãç°¡åãªãµã³ãã«ã次ã«ç€ºããŸãã
#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "main/php_output.h" #include "php_myext.h" static int myext_output_handler(void **nothing, php_output_context *output_context) { char *dup = NULL; dup = estrndup(output_context->in.data, output_context->in.used); php_strtoupper(dup, output_context->in.used); output_context->out.data = dup; output_context->out.used = output_context->in.used; output_context->out.free = 1; return SUCCESS; } PHP_RINIT_FUNCTION(myext) { php_output_handler *handler; handler = php_output_handler_create_internal("myext handler", sizeof("myext handler") -1, myext_output_handler, /* PHP_OUTPUT_HANDLER_DEFAULT_SIZE */ 128, PHP_OUTPUT_HANDLER_STDFLAGS); php_output_handler_start(handler); return SUCCESS; } zend_module_entry myext_module_entry = { STANDARD_MODULE_HEADER, "myext", NULL, /* Function entries */ NULL, NULL, /* Module shutdown */ PHP_RINIT(myext), /* Request init */ NULL, /* Request shutdown */ NULL, /* Module information */ "0.1", /* Replace with version number for your extension */ STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_MYEXT ZEND_GET_MODULE(myext) #endif
èœãšãç©Ž
ã»ãšãã©ã®å Žåããããã¯ææžåãããŠãããäžéšã¯éåžžã«æçœã§ãããäžéšã¯ããŸãå€ããããŸããã æãããªãã®ã¯ãããšãã°ãBVã®ã³ãŒã«ããã¯å ãããããã¡é¢æ°ãåŒã³åºããããããããããŒã¿åºåãæžã蟌ãã ãããªãããã«ããå¿ èŠãããããã§ãã
éèªæãªèœãšãç©Žã«ã¯ãäžéšã®PHPé¢æ°ãå éšBVã䜿çšããŠãããåããããããªã»ãããŸãã¯æ»ããšããäºå®ãå«ãŸããŸãã 次ã®ãããã¡ãã¹ã¿ãã¯ã«ããã·ã¥ãããŸãã ãã®ãããªé¢æ°ã«ã¯ã print_rïŒïŒãhighlight_fileïŒïŒã SoapServer :: handleïŒïŒãå«ãŸããŸãã BVã®ã³ãŒã«ããã¯å ãããããã䜿çšããªãã§ãã ãã-ããã¯äºæž¬ã§ããªãçµæãæãå¯èœæ§ããããŸãã
ãããã«
åºåå±€ã¯ãPHPããã®åºåã®å¯èœæ§ã®ãããæŒããããã£ããããæå®ããããµã€ãºã®ãããã¡ãŒã«ä¿åããäžçš®ã®ãããã¯ãŒã¯ãšæ¯èŒã§ããŸãã ãããã¡ããã£ã±ãã«ãªããšããããã¡ãååšããå Žåã¯ãäžäœã¬ãã«ã«ãã©ãã·ã¥ïŒæžã蟌ã¿ïŒãããŸãã å°ãªããšãå©çšå¯èœãªæãäœããã®-SAPIãããã¡ãžã ãŠãŒã¶ãŒã¯ããããã¡ãŒã®æ°ããµã€ãºãããã³ãããã¡ãŒã®åã¬ã€ã€ãŒã§èš±å¯ãããæäœïŒãã©ãã·ã¥ããã©ãã·ã¥ããŸãã¯åé€ïŒãå¶åŸ¡ã§ããŸãã ããã¯éåžžã«æè»ãªããŒã«ã§ãããããšãã°ãã©ã€ãã©ãªããã³ãã¬ãŒã ã¯ãŒã¯ã®äœæè ãåºåã¹ããªãŒã ãå®å šã«å¶åŸ¡ããã°ããŒãã«ãããã¡ã«éããããã§åŠçããããšãã§ããŸãã ãã®å ŽåãPHPèªäœãããããŒãšåºåã¹ããªãŒã ã®éä¿¡é åºã調æŽããŸãã
ããã©ã«ãã§ã¯ãiniãã¡ã€ã«ã®3ã€ã®èšå®ã«ãã£ãŠå¶åŸ¡ããã1ã€ã®åºåãããã¡ãŒããããŸãã ããã¯ãæžã蟌ã¿æäœã®å®è¡é »åºŠãæžãããSAPIã¬ã€ã€ãŒã«é »ç¹ã«ã¢ã¯ã»ã¹ããªãããã«èšèšãããŠããããããããã¯ãŒã¯ã«ã¢ã¯ã»ã¹ããŸããã ããã¯ãå šäœçãªããã©ãŒãã³ã¹ãåäžãããããã«è¡ãããŸãã ãŸããPHPã®æ¡åŒµæ©èœã¯ãåãããã¡ã§èµ·åãããã³ãŒã«ããã¯ã宣èšã§ããŸããããšãã°ãããŒã¿å§çž®ãæåå眮æãHTTPããããŒå¶åŸ¡ããã®ä»å€ãã®æäœã®ããã§ãã