
PHPã¯ãå®è¡ããå¿
èŠããããã¡ã€ã«ãããã©ã«ãã§ã³ã³ãã€ã«ããã¹ã¯ãªããèšèªã§ãã ã³ã³ãã€ã«äžã«ã
ãªãã³ãŒããæœåºããŠå®è¡ããããã«ç Žæ£ããŸãã PHPã¯ãã®ããã«èšèšãããŸãããRãªã¯ãšã¹ãã®å®è¡ã«ç§»ããšãR-1ãªã¯ãšã¹ãäžã«å®è¡ããããã¹ãŠã®ããšããå¿ãããŸãã
PHPã³ãŒããéçšèŠæ±éã§éçšãµãŒããŒéã§å€æŽãããããšã¯ã»ãšãã©ãããŸããã ãããã£ãŠãã³ã³ãã€ã«äžã¯åžžã«åããœãŒã¹ã³ãŒããèªã¿åãããããããªãã³ãŒãã¯ãŸã£ããåãã§ãããšæ³å®ã§ããŸãã ãŸããã¹ã¯ãªããããšã«æœåºãããšãæéãšãªãœãŒã¹ãç¡é§ã«ãªããŸãã

ã³ã³ãã€ã«æéãé·ãããããªãã³ãŒãããã£ãã·ã¥ããããã®æ¡åŒµæ©èœãéçºãããŸããã ãã®äž»ãªã¿ã¹ã¯ã¯ãåPHPã¹ã¯ãªããã
1åã³ã³ãã€ã«ããçæããããªãã³ãŒããå
±æã¡ã¢ãªã«ãã£ãã·ã¥ããŠãéçšããŒã«ã®ãã¹ãŠã®PHPã¯ãŒã¯ãããŒãããããèªã¿åã£ãŠå®è¡ã§ããããã«ããããšã§ãïŒPHP-FPMãé垞䜿çšãããŸãïŒã
ãã®çµæãèšèªã®å
šäœçãªããã©ãŒãã³ã¹ã倧å¹
ã«åäžããã¹ã¯ãªããã®å®è¡ã«å°ãªããšãååã®æéãããããŸãïŒã¹ã¯ãªããèªäœã«å€§ããäŸåããŸãïŒã PHPã¯åãã¹ã¯ãªãããäœåºŠãã³ã³ãã€ã«ããå¿
èŠããªããããéåžžã¯ããã«å°ãªããªããŸãã
ã¢ããªã±ãŒã·ã§ã³ãè€éã«ãªãã»ã©ããã®æé©åã®å¹çã¯é«ããªããŸãã ããã°ã©ã ãããã¬ãŒã ã¯ãŒã¯ããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ãWordpressã®ãããªè£œåãªã©ã倿°ã®ãã¡ã€ã«ãèµ·åããå Žåãã¹ã¯ãªããã®å®è¡æéã¯10ã15åçããªããŸãã å®éã®ãšãããPHPã³ã³ãã€ã©ã¯ãæ§æãå¥ã®æ§æã«å€æããèšè¿°å
容ãçè§£ããããšããçµæã®ã³ãŒããäœããã®æ¹æ³ã§æé©åããŠå®è¡é床ãäžããå¿
èŠããããããäœéã§ãã ãã®ãããã³ã³ãã€ã©ãŒã¯é
ãã倧éã®ã¡ã¢ãªãæ¶è²»ããŸãã
Blackfireã®ãããªãããã¡ã€ã©ãŒã®å©ããåããŠãã³ã³ãã€ã«ã®æéãäºæž¬ã§ããŸãã

OPCacheã®æŠèŠ
OPCacheã®ãœãŒã¹ã³ãŒãã¯2013幎ã«éãããPHP 5.5.0ã®ããã±ãŒãžã«å«ãŸããããã«ãªããŸããã ãã以æ¥ãããã¯PHPã§ãªãã³ãŒãããã£ãã·ã¥ããããã®æšæºãœãªã¥ãŒã·ã§ã³ã§ãã ããã§ã¯ãä»ã®ãœãªã¥ãŒã·ã§ã³ã«ã€ããŠã¯æ€èšããŸããããªããªããOPCacheãæ¯æããŠãµããŒããæã¡åãããAPCã®ã¿ã«ç²ŸéããŠããããã§ãã ã€ãŸãã以åã«APCã䜿çšããããšãããå Žåã¯ãOPCacheã䜿çšããŸãã
çŸåšããªãã³ãŒãã®åé¡ããã£ãã·ã¥ããããã®PHPéçºè
åãã®æšå¥šãœãªã¥ãŒã·ã§ã³ã§ãã ãã¡ãããå¿
èŠã«å¿ããŠä»ã®ããŒã«ã䜿çšã§ããŸããããªãã³ãŒãããã£ãã·ã¥ããããã«è€æ°ã®æ¡åŒµæ©èœãåæã«ã¢ã¯ãã£ãã«ããããšã¯ã§ããŸãã ã ããã«ãããPHPã確å®ã«ããŠã³ããŸãã
ãŸããOPCacheã®ãããªãéçºã¯PHP 7ã®ãã¬ãŒã ã¯ãŒã¯å
ã§ã®ã¿å®è¡ãããPHP 5ã§ã¯å®è¡ãããªãããšã«æ³šæããŠãã ããããã®èšäºã§ã¯ãéãã確èªã§ããããã«ãäž¡æ¹ã®ããŒãžã§ã³ã®OPCacheãæ€èšããŸãïŒå€§ããããŸããïŒã
ãã®ãããOPCacheã¯æ¡åŒµæ©èœãããæ£ç¢ºã«ã¯zendæ¡åŒµæ©èœã§ãããããŒãžã§ã³5.5.0以éPHPãœãŒã¹ã³ãŒãã«å®è£
ãããŠããŸãã php.iniãä»ããŠéåžžã®ã¢ã¯ãã£ããŒã·ã§ã³ããã»ã¹ã䜿çšããŠã¢ã¯ãã£ããŒãããå¿
èŠããããŸãã ãã£ã¹ããªãã¥ãŒã·ã§ã³ã«ã€ããŠã¯ãããã¥ã¢ã«ããã§ãã¯ããŠãPHPããã³OPCacheãçè§£ããŠãã ããã
1ã€ã®è£œåã®2ã€ã®æ©èœ
OPCacheã«ã¯2ã€ã®äž»èŠãªæ©èœããããŸãã
- ãªãã³ãŒããã£ãã·ã³ã°ã
- ãªãã³ãŒããæé©åããŸãã
OPCacheã¯ã³ã³ãã€ã©ãå®è¡ããŠã³ãŒããååŸããã³ãã£ãã·ã¥ããããããã®ã¹ãããã䜿çšããŠã³ãŒããæé©åã§ããŸãã æ¬è³ªçã«ãç§ãã¡ã¯ããŸããŸãªã³ã³ãã€ã©ã®æé©åã«ã€ããŠè©±ããŠããŸãã OPCacheã¯ãã«ããã¹ã³ã³ãã€ã©ãªããã£ãã€ã¶ãŒãšããŠæ©èœããŸãã

OPCacheå
éš
OPCacheãå
éšã§ã©ã®ããã«æ©èœããããèŠãŠã¿ãŸãããã ã³ãŒãã確èªãããå Žåã¯ãããšãã°
ããããååŸã§ã
ãŸã ã
ãªãã³ãŒãããã£ãã·ã¥ãããšããèãæ¹ã¯ãçè§£ãšåæã容æã«ãªããŸãã Zendãšã³ãžã³ã®äœæ¥ãšã¢ãŒããã¯ãã£ãååã«çè§£ããå¿
èŠããããæé©åãè¡ãããšãã§ããå Žæã«ããã«æ°ä»ãã§ãããã
å
±æã¡ã¢ãªã¢ãã«
ãåç¥ã®ããã«ãç°ãªããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ã¯ãå
±æã¡ã¢ãªã®å€ãã®ã¢ãã«ããããŸãã çŸä»£ã®Unixã·ã¹ãã ã¯ãããã»ã¹ã«ããã¡ã¢ãªã®äžè¬çãªäœ¿çšã«ããã€ãã®ã¢ãããŒãã䜿çšããŠããŸãããæãäžè¬çãªãã®ã¯æ¬¡ã®ãšããã§ãã
- System-V shm API
- POSIX API
- mmap API
- Unixãœã±ããAPI
OSããµããŒãããŠããå ŽåãOPCacheã¯æåã®3ã€ã䜿çšã§ããŸãã
ini -setting
opcache.preferred_memory_modelã¯ãç®çã®ã¢ãã«ãæç€ºçã«
èšå®ããŸãã ãã©ã¡ãŒã¿ãŒãnullã®ãŸãŸã«ãããšãOPCacheã¯ãã©ãããã©ãŒã ã§å®è¡ãããŠããæåã®ã¢ãã«ãéžæããããŒãã«ãé çªã«ç¹°ãè¿ãåŠçããŸãã
static const zend_shared_memory_handler_entry handler_table[] = {
ããã©ã«ãã§ã¯ã
mmapã䜿çšããå¿
èŠããããŸãã ããã¯åªããã¢ãã«ã§ãããéçºãããæç¶å¯èœã§ãã
ipcs
ã
ipcrm
ããã«ãSystem-V SHMã¢ãã«ãããã·ã¹ãã 管çè
ã«ãšã£ãŠæçã§ã¯ãããŸãããã
OPCacheãèµ·åãããšïŒã€ãŸããPHPãèµ·åãããšïŒããã«ãå
±æã¡ã¢ãªã¢ãã«ããã§ãã¯ãã1ã€ã®å€§ããªã»ã°ã¡ã³ããå²ãåœãŠãŸãããã®ã»ã°ã¡ã³ãã¯ãéšåçã«åæ£ãããŸãã ãã®å Žåãã»ã°ã¡ã³ãã¯è§£æŸãŸãã¯ãµã€ãºå€æŽãããªããªããŸãã
ã€ãŸããPHPã®èµ·åæã«ãOPCacheã¯è§£æŸãŸãã¯æçåãããŠããªãã¡ã¢ãªã®1ã€ã®å€§ããªã»ã°ã¡ã³ããå²ãåœãŠãŸãã
opcache.memory_consumption INIèšå®ã䜿çšããŠãã»ã°ã¡ã³ããµã€ãºãã¡ã¬ãã€ãåäœã§èšå®ã§ããŸãã ä¿åããªãã§ããã£ãšèããŠãã ããã
å
±æã¡ã¢ãªã®æ¯æžãèš±å¯ããªãã§ãã ããããããçºçããå Žåãããã»ã¹ã¯ãããã¯ãããŸãã ããã«ã€ããŠã¯ä»¥äžã§èª¬æããŸãã
å¿
èŠã«å¿ããŠã»ã°ã¡ã³ããµã€ãºãèšå®ããŸããPHPããã»ã¹å°çšã®éçšãµãŒããŒã¯ãPHPã ãã§æ°åã®ã¬ãã€ãã®ã¡ã¢ãªãæ¶è²»ããå¯èœæ§ãããããšãå¿ããªãã§ãã ããã ãã®ãããã»ã°ã¡ã³ãã«1 GB以äžãå²ãåœãŠãããšããããããŸããããã¹ãŠç¹å®ã®ããŒãºã«äŸåããŸãã 倿°ã®äŸåé¢ä¿ãªã©ãåããããã¬ãŒã ã¯ãŒã¯ã«åºã¥ããææ°ã®ã¢ããªã±ãŒã·ã§ã³ã¹ã¿ãã¯ã䜿çšããå Žåã¯ãå°ãªããšãã®ã¬ãã€ããªãã§ã¯å®è¡ã§ããŸããã
ã»ã°ã¡ã³ãã¯ãOPCacheã«ãã£ãŠããã€ãã®ã¿ã¹ã¯ã«äœ¿çšãããŸãã
- ãªãã³ãŒãã®ãã£ãã·ã¥ãå«ããã¹ã¯ãªããããŒã¿æ§é ã®ãã£ãã·ã¥ã
- å
±æã€ã³ã¿ãŒã³æååãããã¡ãäœæããŸãã
- ãã£ãã·ã¥ãããã¹ã¯ãªããã®ããã·ã¥ããŒãã«ãä¿åããŸãã
- OPCacheã°ããŒãã«å
±æã¡ã¢ãªã®ç¶æ
ãä¿åããŸãã
å
±æã¡ã¢ãªã»ã°ã¡ã³ãã«ã¯ããªãã³ãŒãã ãã§ãªããOPCacheãæ©èœããããã«å¿
èŠãªãã®ä»ã®ãã®ãå«ãŸããŠããããšã«æ³šæããŠãã ããã ãããã£ãŠãå¿
èŠãªã¡ã¢ãªéãèŠç©ãããå¿
èŠãªã»ã°ã¡ã³ããµã€ãºãèšå®ããŸãã

ãªãã³ãŒããã£ãã·ã³ã°
ãã£ãã·ã³ã°ã¡ã«ããºã ã®è©³çŽ°ãæ€èšããŠãã ããã
ã¢ã€ãã¢ã¯ãåãã€ã³ã¿ã®ããŒã¿ãå
±æã¡ã¢ãªïŒshmãå
±æã¡ã¢ãªïŒã«ã³ããŒããããšã§ãããã®ããŒã¿ã¯ãèŠæ±ããšã«å€åããŸãããã€ãŸããäžå€ããŒã¿ã§ãã ãããããããŸãã å
±æã¡ã¢ãªãã以åã«äœ¿çšãããã¹ã¯ãªãããããŒãããåŸããã€ã³ã¿ããŒã¿ã¯ããã»ã¹ã®æšæºã¡ã¢ãªã«åŸ©å
ãããçŸåšã®ãªã¯ãšã¹ãã«é¢é£ä»ããããŸãã åäœããPHPã³ã³ãã€ã©ã¯ãZend Memory ManagerïŒZend Memory ManagerãZMMïŒã䜿çšããŠåãã€ã³ã¿ãŒãé
眮ããŸãã ãã®ã¿ã€ãã®ã¡ã¢ãªã¯ãªã¯ãšã¹ãã«é¢é£ä»ããããŠãããããZMMã¯çŸåšã®ãªã¯ãšã¹ããå®äºãããšèªåçã«ãã€ã³ã¿ãè§£æŸããããšããŸãã ããã«ããããã®ãã€ã³ã¿ãŒã¯çŸåšã®èŠæ±ã®ããŒãããé
眮ããããããä»ã®PHPããã»ã¹ãšå
±æã§ããªããã©ã€ããŒãæ¡åŒµã¡ã¢ãªã®ãããªãã®ã§ããããšãããããŸãã ãããã£ãŠãOPCacheã®ã¿ã¹ã¯ã¯ããã€ã³ã¿ãŒããã®ããŒã«ã«å²ãåœãŠããŸãŸã«ããªãã§ãå²ãåœãŠãããå
±æã¡ã¢ãªããŒã«ã«ã³ããŒããããã«ãPHPã³ã³ãã€ã©ã«ãã£ãŠè¿ãããåæ§é ã調ã¹ãããšã§ãã ãããŠãããã§ã³ã³ãã€ã«æéã«ã€ããŠè©±ããŠããŸãã ã³ã³ãã€ã©ã«ãã£ãŠæçš¿ããããã®ã¯ãã¹ãŠäžå€ãšèŠãªãããŸãã å¯å€ããŒã¿ã¯ãå®è¡æã«
Zendä»®æ³ãã·ã³ã«ãã£ãŠäœæããããããZendã³ã³ãã€ã©ãŒã«ãã£ãŠäœæããããã¹ãŠãå
±æã¡ã¢ãªã«å®å
šã«ä¿åã§ããŸãã äŸãã°ã颿°ãšã¯ã©ã¹ã颿°åãžã®ãã€ã³ã¿ãŒãOPArray颿°ãžã®ãã€ã³ã¿ãŒãã¯ã©ã¹å®æ°ã宣èšãããã¯ã©ã¹å€æ°ã®ååããããŠæåŸã«ããããã®ããã©ã«ãã®å
容...å€ãã®ããšãPHPã³ã³ãã€ã©ãŒã«ãã£ãŠã¡ã¢ãªãŒå
ã«äœæãããŸãã
ãã®ã¢ãã«ã¯ãããã¯ã確å®ã«é²æ¢ããããã«äœ¿çšãããŸãã åŸã»ã©ãããããã³ã°ã®ãããã¯ã«è§ŠããŸãã æ¬è³ªçã«ãOPCacheã¯å®è¡åã«ãã¹ãŠã®äœæ¥ãããã«å®è¡ãããããOPCacheã¹ã¯ãªããã®å®è¡äžã«è¡ãããšã¯ãããŸããã å¯å€ããŒã¿ã¯ãZMMã䜿çšããŠããã»ã¹ã®ã¯ã©ã·ãã¯ããŒãã§äœæãããäžå€ããŒã¿ã¯å
±æã¡ã¢ãªãã埩å
ãããŸãã
ãã®ãããOPCacheã¯ã³ã³ãã€ã©ãŒã«æ¥ç¶ããåŸè
ãã¹ã¯ãªããã®ã³ã³ãã€ã«äžã«åããã¹ãæ§é ãç¬èªã®ã³ã³ãã€ã©ãŒã«çœ®ãæããŸãã æ¬¡ã«ãZendãšã³ãžã³ã®ããŒãã«ãšå
éšæ§é ãçŽæ¥èšå®ãã代ããã«ã
persistent_script
æ§é ãèšå®ããããã³ã³ãã€ã©ãŒã«åŒ·å¶ããŸãã
ããã«ãããŸãïŒ
typedef struct _zend_persistent_script { ulong hash_value; char *full_path; unsigned int full_path_len; zend_op_array main_op_array; HashTable function_table; HashTable class_table; long compiler_halt_offset; int ping_auto_globals_mask; accel_time_t timestamp; zend_bool corrupted;
ãã®ãããOPCacheã¯ã颿°ãã€ã³ã¿ãŒãåãæ¿ããã ãã§ãã³ã³ãã€ã©ãŒæ§é ãpersistent_scriptã«çœ®ãæããŸãã
new_persistent_script = create_persistent_script(); orig_active_op_array = CG(active_op_array); orig_function_table = CG(function_table); orig_class_table = CG(class_table); orig_user_error_handler = EG(user_error_handler); CG(function_table) = &ZCG(function_table); EG(class_table) = CG(class_table) = &new_persistent_script->class_table; EG(user_error_handler) = NULL; zend_try { orig_compiler_options = CG(compiler_options); CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY; CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES; CG(compiler_options) |= ZEND_COMPILE_DELAYED_BINDING; CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION; op_array = *op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC); CG(compiler_options) = orig_compiler_options; } zend_catch { op_array = NULL; do_bailout = 1; CG(compiler_options) = orig_compiler_options; } zend_end_try(); CG(active_op_array) = orig_active_op_array; CG(function_table) = orig_function_table; EG(class_table) = CG(class_table) = orig_class_table; EG(user_error_handler) = orig_user_error_handler;
ã芧ã®ãšãããPHPã³ã³ãã€ã©ã¯å®å
šã«åé¢ãããŠãããéåžžã®ããŒã¿ãå«ãŸããããŒãã«ããã¯åãé¢ãããŠããŸãã çŸåšã
persistent_script
æ§é ã«ããŒã¿ãåã蟌ã¿ãŸãã æ¬¡ã«ãOPCacheã¯ãããã®æ§é ã調ã¹ãŠãèŠæ±ãã€ã³ã¿ãŒãå
±æã¡ã¢ãªãžã®ãã€ã³ã¿ãŒã«çœ®ãæããå¿
èŠããããŸãã OPCacheã®ããŒãºïŒ
- ã¹ã¯ãªãã颿°ã
- ã¹ã¯ãªããã¯ã©ã¹
- ã¡ã€ã³ã®OPArrayã¹ã¯ãªããã
- ã¹ã¯ãªãããã¹
- ã¹ã¯ãªããèªäœã®æ§é ã

ã³ã³ãã€ã©ãŒã«ã¯ãæé©åãç¡å¹ã«ããããã€ãã®ãªãã·ã§ã³ïŒããšãã°ã
ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION
ããã³
ZEND_COMPILE_DELAYED_BINDING
ïŒãäžããããŸãã ããã«ãããOPCacheã®äœæ¥ã远å ãããŸãã OPCacheã¯Zendãšã³ãžã³ã«æ¥ç¶ããããšã«æ³šæããŠãã ãããããã¯ãœãŒã¹ã³ãŒãã®ãããã§ã¯ãããŸããã
ããã§
persitent_script
æ§é ãã§ããã®ã§ããã®æ
å ±ããã£ãã·ã¥ããå¿
èŠããããŸãã PHPã³ã³ãã€ã©ã¯æ§é ãåããŸããããZMMã®å©ããåããŠãšããžããã¡ã¢ãªãå²ãåœãŠãŸãããçŸåšã®ãªã¯ãšã¹ãã®æåŸã«è§£æŸãããŸãã æ¬¡ã«ããã®ã¡ã¢ãªã調ã¹ãŠããã®å
容ãå
±æã¡ã¢ãªã»ã°ã¡ã³ãã«ã³ããŒããŠãåéãããæ
å ±ãè€æ°ã®ã¯ãšãªã«äœ¿çšããæ¯ååèšç®ããªãããã«ããå¿
èŠããããŸãã
ããã»ã¹ã®æ§é ã¯æ¬¡ã®ãšããã§ãã
- PHPã¹ã¯ãªããããã£ãã·ã¥ãããå倿°ïŒãã¹ãŠã®ãã€ã³ã¿ãŒã¿ãŒã²ããïŒã®åèšããŒã¿ãµã€ãºãèšç®ãããŸãã
- ãã§ã«å²ãåœãŠãããŠããå
±æã¡ã¢ãªã¯ãåããµã€ãºã®å€§ããªãããã¯ã1ã€äºçŽããŸãã
- ã¹ã¯ãªãã倿°ã®ãã¹ãŠã®æ§é ãã¹ãã£ã³ããããã€ã³ã¿ãŒã®ãã¹ãŠã®ã¿ãŒã²ãããªããžã§ã¯ãã®å€æ°ã®ããŒã¿ãå
±æã¡ã¢ãªã®æ°ããäºçŽããããããã¯ã«ã³ããŒãããŸãã
- ã¹ã¯ãªãããããŠã³ããŒãããã«ã¯ïŒãã®ããšã«ãªããšïŒãæ£å察ãè¡ãããŸãã
ãã®ãããOPCacheã¯å
±æã¡ã¢ãªãã€ã³ããªãžã§ã³ãã«äœ¿çšãããªãªãŒã¹ãé«å¯åºŠåã«ãã£ãŠæçåããããšã¯ãããŸããã ã¹ã¯ãªããããšã«ãæ
å ±ãä¿åããããã«å¿
èŠãªåèšã¡ã¢ãªã®æ£ç¢ºãªãµã€ãºãèšç®ããããã«ããŒã¿ãã³ããŒããŸãã
ã¡ã¢ãªãè§£æŸãããããOPCacheã«è¿ããããããããšã¯ãããŸããã ãããã£ãŠãéåžžã«å¹ççã«äœ¿çšãããæçåãããŸããã ããã«ãããå
±æã¡ã¢ãªã®ããã©ãŒãã³ã¹ã倧å¹
ã«åäžããŸããããã¯ãïŒmalloc / freeã®ããã«ïŒè§£æŸã§ããã¡ã¢ãªã管çããªãããä¿åããã³è¡šç€ºãããªã³ã¯ãªã¹ããŸãã¯BããªãŒïŒBTreeïŒããªãããã§ãã OPCacheã¯å
±æã¡ã¢ãªã»ã°ã¡ã³ãã«ããŒã¿ãä¿åããã¹ã¯ãªããã®é¢é£æ§ã確èªããããã«é¢é£æ§ã倱ããããšããããã¡ãŒã¯è§£æŸãããŸãããããç¡é§ããšããŒã¯ãããŸãã 倱ãããã¡ã¢ãªã®å²åãæå€§ã«éãããšãOPCacheãåèµ·åããŸãã ãã®ã¢ãã«ã¯ãããšãã°APCãšã¯å€§ããç°ãªããŸãã ãã®å€§ããªå©ç¹ã¯ãå
±æã¡ã¢ãªããã®ãããã¡ã管çãããªãïŒè§£æŸãããªããå§çž®ãããªããªã©ïŒãããæéã®çµéãšãšãã«ããã©ãŒãã³ã¹ãäœäžããªãããšã§ãã ãããã®ã¡ã¢ãªç®¡çæäœã¯ãã¹ãŠçŽç²ã«æè¡çãªãã®ã§ãããæ©èœãæ¹åããã®ã§ã¯ãªããçç£æ§ãäœäžãããŸãã
OPCacheã¯ãPHPç°å¢ã®å®è¡ãèæ
®ããŠãå¯èœãªéãæé«ã®ããã©ãŒãã³ã¹ãæäŸããããã«èšèšãããŸããã å
±æã¡ã¢ãªã»ã°ã¡ã³ãã®ãäžå¯äŸµãã¯ãéåžžã«åªããããã»ããµãã£ãã·ã¥ãããçïŒç¹ã«L1ããã³L2ïŒãæäŸããŸããããã¯ãOPCacheãã¡ã¢ãªãã€ã³ã¿ãL1 / L2ã«æããããã§ãã
ã¹ã¯ãªããã®ãã£ãã·ã¥ã«ã¯ãäž»ã«ãã®ããŒã¿ã®æ£ç¢ºãªãµã€ãºã®èšç®ãå«ãŸããŸãã èšç®ã¢ã«ãŽãªãºã ã¯æ¬¡ã®ãšããã§ãã
uint zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, char *key, unsigned int key_length TSRMLS_DC) { START_SIZE(); ADD_SIZE(zend_hash_persist_calc(&new_persistent_script->function_table, (int (*)(void* TSRMLS_DC)) zend_persist_op_array_calc, sizeof(zend_op_array) TSRMLS_CC)); ADD_SIZE(zend_accel_persist_class_table_calc(&new_persistent_script->class_table TSRMLS_CC)); ADD_SIZE(zend_persist_op_array_calc(&new_persistent_script->main_op_array TSRMLS_CC)); ADD_DUP_SIZE(key, key_length + 1); ADD_DUP_SIZE(new_persistent_script->full_path, new_persistent_script->full_path_len + 1); ADD_DUP_SIZE(new_persistent_script, sizeof(zend_persistent_script)); RETURN_SIZE(); }
ç¹°ãè¿ããŸãïŒãã£ãã·ã¥ããå¿
èŠããããŸãïŒ
- ã¹ã¯ãªãã颿°ã
- ã¹ã¯ãªããã¯ã©ã¹
- ã¡ã€ã³ã®OPArrayã¹ã¯ãªããã
- ã¹ã¯ãªãããã¹
- ã¹ã¯ãªããèªäœã®æ§é ã
å埩ã¢ã«ãŽãªãºã ã¯ã颿°ãã¯ã©ã¹ãããã³OPArrayã®è©³çްæ€çŽ¢ãå®è¡ããŸãããã¹ãŠã®ãã€ã³ã¿ãŒã®ããŒã¿ããã£ãã·ã¥ããŸãã ããšãã°ãPHP 5ã§ã¯ã颿°ã®å Žåãå
±æã¡ã¢ãªïŒshmïŒã«ã³ããŒããå¿
èŠããããŸãã
- 颿°ããã·ã¥ããŒãã«
- 颿°ã®ããã·ã¥ããŒãã«ã®ã³ã³ããããŒãã«ïŒãã±ãã**ïŒ
- 颿°ããã·ã¥ããŒãã«ã³ã³ãããŒïŒãã±ãã*ïŒ
- 颿°ããã·ã¥ããŒãã«ã³ã³ãããŒããŒïŒchar *ïŒ
- 颿°ããã·ã¥ããŒãã«ã³ã³ãããŒããŒã¿ãã€ã³ã¿ãŒïŒvoid *ïŒ
- 颿°ããã·ã¥ããŒãã«ã³ã³ãããŒããŒã¿ïŒ*ïŒ
- OPArray颿°
- OPArrayãã¡ã€ã«åïŒchar *ïŒ
- OPArrayãªãã©ã«ïŒååïŒcharïŒããã³å€ïŒzvalïŒ ïŒ
- OPArrayãªãã³ãŒãïŒzend_op *ïŒ
- 颿°åOPArray颿°åïŒchar *ïŒ
- arg_infos OPArrayïŒzend_arg_infoã ååãšã¯ã©ã¹åã¯äž¡æ¹ãšãcharã®ãããªãã®ã§ã ïŒ
- é
åãã¬ãŒã¯ç¶ç¶OPArrayïŒzend_brk_cont_element *ïŒ
- éç倿°OPArrayïŒå®å
šãªããã·ã¥ããŒãã«ãšzval *ïŒ
- OPArrayã®ããã¥ã¡ã³ãã³ã¡ã³ãïŒchar *ïŒ
- é
åtry-catch OPArray try-ïŒzend_try_catch_element *ïŒ
- ã³ã³ãã€ã«ãããOPArray倿°ïŒzend_compiled_variable *ïŒ
PHP 7ã§ã¯ãæ§é ïŒããã·ã¥ããŒãã«ãªã©ïŒã®éãã«ããããªã¹ãã¯ãããã«ç°ãªããŸãã ç§ãèšã£ãããã«ãã¢ã€ãã¢ã¯ãã¹ãŠã®ãã€ã³ã¿ã®ããŒã¿ãå
±æã¡ã¢ãªã«ã³ããŒããããšã§ãã ãã£ãŒãã³ããŒã«ã¯æ§é ã®éè€ãå«ãŸããå ŽåããããããOPCacheã¯å€æããŒãã«ã䜿çšããŠãã€ã³ã¿ãŒãæ ŒçŽããŸãïŒãã€ã³ã¿ãŒãèŠæ±ã«é¢é£ä»ããããéåžžã®ã¡ã¢ãªããå
±æã¡ã¢ãªã«ã³ããŒããããã³ã«ãå€ããã€ã³ã¿ãŒã¢ãã¬ã¹ãšæ°ãããã€ã³ã¿ãŒã¢ãã¬ã¹éã®æ¥ç¶ãããŒãã«ã«æžã蟌ãŸããŸãã ã³ããŒãåŠçããããã»ã¹ã¯ããŸã倿ããŒãã«ã§ãã®ããŒã¿ãæ¢ã«ã³ããŒãããŠãããã©ããã調ã¹ãŸãã ã³ããŒãããå Žåãå€ããã€ã³ã¿ãŒããŒã¿ã䜿çšããããããéè€ã¯ãããŸããã
void *_zend_shared_memdup(void *source, size_t size, zend_bool free_source TSRMLS_DC) { void **old_p, *retval; if (zend_hash_index_find(&xlat_table, (ulong)source, (void **)&old_p) == SUCCESS) { return *old_p; } retval = ZCG(mem);; ZCG(mem) = (void*)(((char*)ZCG(mem)) + ZEND_ALIGNED_SIZE(size)); memcpy(retval, source, size); if (free_source) { interned_efree((char*)source); } zend_shared_alloc_register_xlat_entry(source, retval); return retval; }
ZCG(mem)
ã¯ãèŠçŽ ã远å ããããšãã£ã±ãã«ãªãåºå®ãµã€ãºã®å
±æã¡ã¢ãªã»ã°ã¡ã³ãã§ãã æ¢ã«å²ãåœãŠãããŠãããããåã³ããŒã«ã¡ã¢ãªãå²ãåœãŠãå¿
èŠã¯ãããŸããïŒããã«ããå
šäœã®ããã©ãŒãã³ã¹ãäœäžããŸãïŒãã»ã°ã¡ã³ããåãããšãããã€ã³ã¿ã®ã¢ãã¬ã¹ã®å¢çãã·ããããŸãã
ãªã¯ãšã¹ãã«é¢é£ä»ããããããŒããããã€ã³ã¿ãšããŒã¿ãååŸãããããå
±æã¡ã¢ãªã«ã³ããŒãããã¹ã¯ãªãããã£ãã·ã¥ã¢ã«ãŽãªãºã ã調ã¹ãŸããã ããŒãã¢ã«ãŽãªãºã ã¯ãŸã£ããéã®åŠçãè¡ããŸããå
±æã¡ã¢ãªãã
persistent_script
ãååŸãããã¹ãŠã®åçæ§é ãã¹ãã£ã³ããŠãå
±æãã€ã³ã¿ãããã»ã¹ããŠã³ãã¡ã¢ãªã«ãããã€ã³ã¿ã«ã³ããŒããŸãã ãã®åŸãã¹ã¯ãªããã¯Zendãšã³ãžã³ïŒZend Engine ExecutorïŒã䜿çšããŠèµ·åã§ããããã«ãªããäžè¬çãªãã€ã³ã¿ãŒã®ã¢ãã¬ã¹ãåã蟌ãŸããªããªããŸããïŒããã¹ã¯ãªãããå¥ã®ã¹ã¯ãªããã®æ§é ã倿Žãããšãæ·±å»ãªãã°ãçºçããŸãïŒã çŸåšãZendã¯OPCacheã«ã ãŸãããŠããŸãã圌ã¯ãã¹ã¯ãªããã®å®è¡ããã€ã³ã¿ãŒã®çœ®æã®åã«äœãèµ·ãã£ããã«æ°ä»ããŸããã§ããã
éåžžã®ã¡ã¢ãªããå
±æã¡ã¢ãªãžã®ã³ããŒïŒã¹ã¯ãªãããã£ãã·ã³ã°ïŒããã³ãã®éïŒã¹ã¯ãªããã®èªã¿èŸŒã¿ïŒã®ããã»ã¹ã¯æé©åãããŠãããããã©ãŒãã³ã¹ãåäžãããªãã³ããŒãŸãã¯ããã·ã¥æ€çŽ¢ã倿°å®è¡ããå¿
èŠãããå Žåã§ããæ¯åPHPã³ã³ãã€ã©ãå®è¡ãããããã¯ããã«é«éã§ãã
å
éšæååã¹ãã¬ãŒãžã®å
±æ
ã€ã³ã¿ãŒã³ãããæååã¯ãPHP 5.4ã§å°å
¥ãããåªããã¡ã¢ãªæé©åã§ãã ããã¯è«ççã«èŠããŸãïŒPHPãæååïŒchar *ïŒãæ€åºãããšããããç¹å¥ãªãããã¡ãŒã«ä¿åããåãæååãæ€åºããããã³ã«ãã€ã³ã¿ãŒãåã³äœ¿çšããŸãã
次ã®ããã«æ©èœããŸãã

ãã¹ãŠã®ãã€ã³ã¿ãŒã¯åãæååã€ã³ã¹ã¿ã³ã¹ã䜿çšããŸãã ãã ãã1ã€ã®åé¡ããããŸãããã®å
éšè¡ã®ãããã¡ãŒã¯ããã»ã¹ããšã«åå¥ã«äœ¿çšãããäž»ã«PHPã³ã³ãã€ã©ãŒã«ãã£ãŠå¶åŸ¡ãããŸãã ã€ãŸããPHP-FPMããŒã«ã§ã¯ãåPHPã¯ãŒã¯ãããŒããã®ãããã¡ãŒã®ç¬èªã®ã³ããŒãä¿åããŸãã ãã®ãããªãã®ïŒ

ããã¯ãç¹ã«å€ãã®ã¯ãŒã¯ãããŒãããå Žåãããã³ã³ãŒãã§éåžžã«å€§ããªæååã䜿çšããå ŽåïŒãã³ãïŒPHPã®èª¬æã³ã¡ã³ãã¯æååã§ãïŒã倧ããªã¡ã¢ãªæå€±ã«ã€ãªãããŸãã
OPCacheã¯ãããŒã«å
ã®ãã¹ãŠã®ã¯ãŒã¯ãããŒéã§ãã®ãããã¡ãŒãå
±æããŸãã ãã®ãããªãã®ïŒ

OPCacheã¯ãå
±æã¡ã¢ãªã»ã°ã¡ã³ãã䜿çšããŠããããã®å
±æãããã¡ããã¹ãŠæ ŒçŽããŸãã ãããã£ãŠãã»ã°ã¡ã³ããµã€ãºãå²ãåœãŠããšãã¯ãå
éšè¡ã¹ãã¬ãŒãžã®äœ¿çšãèæ
®ããå¿
èŠããããŸãã
opcache.interned_strings_bufferã®INIæ§æã䜿çšããŠãã¹ãã¬ãŒãžã«å
±æã¡ã¢ãªã䜿çšããæ¹æ³ãæ§æã§ããŸãã ããäžåºŠæãåºãããŠãã ãããååãªã¡ã¢ãªãå²ãåœãŠãããŠããããšã確èªããŠãã ããã ãããã®è¡
ã®ã¹ããŒã¹ã
äžè¶³ããå ŽåïŒ
opcache.interned_strings_bufferãäœãããïŒãOPCacheã¯åèµ·åããŸããã çµå±ã圌ã«ã¯ãŸã ååãªç©ºãå
±æã¡ã¢ãªããããæååã¹ãã¬ãŒãžãããã¡ã®ã¿ããã£ã±ãã§ããªã¯ãšã¹ãã®åŠçããããã¯ããŸããã åã«æååãä¿åããã³å
±æããããšã¯ã§ãããPHPã¯ãŒã¯ãããŒã®ã¡ã¢ãªã䜿çšããæååã«ãã¢ã¯ã»ã¹ã§ããªããªããŸãã ããã©ãŒãã³ã¹ã«åœ±é¿ãäžããªãããã«ããã®ãããªç¶æ³ãåé¿ããããšãæåã§ãã
ãã°ã確èªããŠãã ããããã®ããã«ã¡ã¢ãªãäžè¶³ãããšãOPCacheã¯ããã«ã€ããŠèŠåããŸãã
if (ZCSG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >= ZCSG(interned_strings_end)) { zend_accel_error(ACCEL_LOG_WARNING, "Interned string buffer overflow"); return arKey; }
ãã®ãããªè¡ã«ã¯ãPHPã³ã³ãã€ã©ã®æäœäžã«ééããã»ãŒãã¹ãŠã®çš®é¡ã®è¡ãå«ãŸããŸãã倿°åããphpè¡ãã颿°åãã¯ã©ã¹å...ã³ã¡ã³ãã¯ã仿¥ã泚éããšåŒã°ããã»ãšãã©ã®å Žåã巚倧ãªãµã€ãºã ãããã¯ã»ãšãã©ã®ãããã¡ãå æããã®ã§ãå¿ããªãã§ãã ããã
ããã¯æ©æ§
å
±æã¡ã¢ãªã«ã€ããŠè©±ããŠããã®ã§ãã¡ã¢ãªããããã³ã°ã¡ã«ããºã ã«ã€ããŠã話ãåãå¿
èŠããããŸãã æ¬è³ªã¯ããã§ãïŒ
å
±æã¡ã¢ãªã«æžã蟌ã¿ãããã¹ãŠã®PHPããã»ã¹ã¯ãå
±æã¡ã¢ãªã«æžã蟌ã¿ããä»ã®ãã¹ãŠã®ããã»ã¹ããããã¯ããŸã ã ãããã£ãŠãäž»ãªåé¡ã¯èªæžã§ã¯ãªããå·çã«é¢é£ããŠããŸãã å
±æã¡ã¢ãªããèªã¿èŸŒãPHPããã»ã¹ã¯150åãããŸãããåæã«æžã蟌ãããšãã§ããã®ã¯1ã€ã ãã§ãã æžãèŸŒã¿æäœã¯èªã¿åãããããã¯ãããä»ã®æžãèŸŒã¿æäœã®ã¿ããããã¯ããŸãã
ãã®ãã
ãOPCacheã§ã¯
ããã£ãã·ã¥ã倧å¹
ã«ãŠã©ãŒã ã¢ãããããŸã§ãããããã¯ã¯çºçããŸãã ã ã³ãŒãããããã€ããåŸããµãŒããŒãžã®ãã©ãã£ãã¯ãèŠå¶ããªãå Žåãã¹ã¯ãªããã¯éäžçã«ã³ã³ãã€ã«ããã³ãã£ãã·ã¥ããå§ããŸãã ãŸããå
±æã¡ã¢ãªã«ãã£ãã·ã¥ãæžã蟌ãæäœã¯æä»ããã¯ã®å¯Ÿè±¡ãšãªãããã幞éãªäººãã¡ã¢ãªãžã®æžã蟌ã¿ãéå§ããä»ã®å
šå¡ããããã¯ããããããã¹ãŠã®ããã»ã¹ãèµ·åããŸãã ãããŠãããã¯ãè§£é€ãããšã䞊ãã§åŸ
æ©ããŠããä»ã®ãã¹ãŠã®ããã»ã¹ã¯ãã³ã³ãã€ã«ããã°ããã®ãã¡ã€ã«ããã§ã«å
±æã¡ã¢ãªã«ä¿åãããŠããããšãçºèŠããŸãã ãããŠãå
±æã¡ã¢ãªããããŒã¿ãããŒãããããã«ãã³ã³ãã€ã«çµæãç Žæ£ãå§ããŸãã ããã¯èš±ãããªããªãœãŒã¹ã®æµªè²»ã§ãã
zend_shared_alloc_lock(TSRMLS_C); bucket = zend_accel_hash_find_entry(&ZCSG(hash), new_persistent_script->full_path, new_persistent_script->full_path_len + 1); if (bucket) { zend_persistent_script *existing_persistent_script = (zend_persistent_script *)bucket->data; if (!existing_persistent_script->corrupted) { if (!ZCG(accel_directives).revalidate_path && (!ZCG(accel_directives).validate_timestamps || (new_persistent_script->timestamp == existing_persistent_script->timestamp))) { zend_accel_add_key(key, key_length, bucket TSRMLS_CC); } zend_shared_alloc_unlock(TSRMLS_C); return new_persistent_script; } }
ãµãŒããŒãå€éšãã©ãã£ãã¯ããåæããæ°ããã³ãŒããå±éããæãéãURLãcurlã§èª¿æŽããŠãcurlãªã¯ãšã¹ããå
±æã¡ã¢ãªãåŸã
ã«æºããããã«ããå¿
èŠããããŸãã ã»ãšãã©ã®ã¹ã¯ãªãããå®äºãããããã©ãã£ãã¯ããµãŒããŒã«éä¿¡ã§ããŸããå
±æã¡ã¢ãªããã®ã¢ã¯ãã£ããªèªã¿åããéå§ãããããã«ããããã¯ãçºçããããšã¯ãããŸããã ãã¡ããããŸã ã³ã³ãã€ã«ãããŠããªãå°ããªã¹ã¯ãªãããååšããå ŽåããããŸããããããã¯ã»ãšãã©ãªããããèšé²ã®ããããã³ã°ã«ã¯ã»ãšãã©åœ±é¿ããŸããã
PHPãã¡ã€ã«ã®æžã蟌ã¿äžããã³ãã®äœ¿çšäžã¯é¿ããŠãã ããã ãã®çç±ã¯åãã§ããå®çšŒåãµãŒããŒã®ã«ãŒããã©ã«ããŒã«æ°ãããã¡ã€ã«ãæžã蟌ãã§ãã䜿çšããå Žåãã€ãŸããæ°åã®ã¯ãŒã¯ããã»ã¹ãã³ã³ãã€ã«ããŠå
±æã¡ã¢ãªã«ãã£ãã·ã¥ããããšããå¯èœæ§ããããŸãã ãããŠãããã¯ããããŸãã PHP- OPCache INI-
opcache.blacklist-filename ( (glob pattern)).
, Unix â
fcntl()
:
void zend_shared_alloc_lock(TSRMLS_D) { while (1) { if (fcntl(lock_file, F_SETLKW, &mem_write_lock) == -1) { if (errno == EINTR) { continue; } zend_accel_error(ACCEL_LOG_ERROR, "Cannot create lock - %s (%d)", strerror(errno), errno); } break; } ZCG(locked) = 1; zend_hash_init(&xlat_table, 100, NULL, NULL, 1); }
, : , , .
, : . .
OPCache
:
- PHP ( PHP-FPM) OPCache , .
- OPCache . .
- OPCache .
- :
- , .
- .
- - .
- OPCache.
, OPCache ( , INI-
opcache.revalidate_freq ) , . : , . PHP OPCache, PHP (
stat()
) : OPCache , «»
stat()
.
(timestamp)
opcache.validate_timestamps opcache.revalidate_freq , , OPCache «wasted».
OPCache INI- opcache.max_wasted_percentage INI. . ä»ã®ãªãã·ã§ã³ã¯ãããŸããã
memory_used = zend_accel_script_persist_calc(new_persistent_script, key, key_length TSRMLS_CC); ZCG(mem) = zend_shared_alloc(memory_used); if (!ZCG(mem)) { zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC); zend_shared_alloc_unlock(TSRMLS_C); return new_persistent_script; }

, , . «», OPCache . .
, . OPCache , . , : , . - . , , . .
., production-, ( , : OPCache persistent-, ). :
- ( ).
- OPCache (
opcache_reset()
) FPM ( , â )). - .
- FPM, , curl- .
- .
shell- 50 . ,
lsof
kill
. Unix ;-)
GUI- OPCache.
opcache_get_status()
:

.
(cache keys) .
OPCache , -, . - OPCache . ? .
OPCache . ,
realpath_cache , . ,
opcache.revalidate_path 1 realpath cache ( , , ).
, OPCache ,
realpath . , INI-
opcache.revalidate_path 1. , OPCache
unresolved . , , , OPCache - unresolved , ( ).
opcache.use_cwd 1, OPCache
cwd
.
,
require_once "./foo.php";
ã , PHP ( ),
opcache.use_cwd 1. , ,
opcache.revalidate_path .
realpath- . www- , OPCache ,
opcache_reset()
.
- realpath- .
opcache.use_cwd opcache.revalidate_path 1, . realpath OPCache, PHP ,
realpath_cache
.
, documentroot. , FPM- FastCGI, . , Lighttpd Nginx:
- ( ).
- FPM, PHP ( OPCache). , realpath-, . FPM. , , .
- .
- FPM-. curl- .
- .
, , :
- , PHP- FPM- production-.
- FPM-, . production-.
- FPM-: , .
- documentroot- , FPM-.
- , , , , . , documentroot- ( realpath-), . , production-. shell- 80.
, OPCache . : . OPCache , , : .
, .
OPCache
opcache_get_status()
â , GUI â
num_cached_keys . : INI-
opcache.max_accelerated_files . , OPCache . , . .
require_once
, OPCache . ,
include_once
, .
OPCache - persistent-, . - , . .
num_cached_scripts num_cached_keys , OPache.
num_cached_keys .
max_cached_keys , .
, , , OPache (INI-
opcache.log_verbosity_level ). , , , OOM- (OutOfMemory): -.

static void zend_accel_add_key(char *key, unsigned int key_length, zend_accel_hash_entry *bucket TSRMLS_DC) { if (!zend_accel_hash_find(&ZCSG(hash), key, key_length + 1)) { if (zend_accel_hash_is_full(&ZCSG(hash))) { zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!"); ZSMMG(memory_exhausted) = 1; zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH TSRMLS_CC); } else { char *new_key = zend_shared_alloc(key_length + 1); if (new_key) { memcpy(new_key, key, key_length + 1); if (zend_accel_hash_update(&ZCSG(hash), new_key, key_length + 1, 1, bucket)) { zend_accel_error(ACCEL_LOG_INFO, "Added key '%s'", new_key); } } else { zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC); } } } }
:

PHP OPCache,
opcache.memory_consumption (shm). (
opcache.interned_strings_buffer ). - persistent- .
opcache.max_accelerated_files .
OPCache, . OPCache ( ). «», OPCache, ().
:

- persistent- , , OPCache ( ).
OPCache
, , Symfony, :
- production ( opcache.validate_timestamps 0)
- , runtime . Symfony.
- :
- opcache.memory_consumption . .
- opcache.interned_strings_buffer . . : OPCache , , «» PHP ( opcache.save_comments = 1 ), , , .
- opcache.max_accelerated_files . . , .
- opcache.opcache.revalidate_path opcache.use_cwd . .
- opcache.enable_file_override , .
- opcache.blacklist_filename , runtime. .
- opcache.consistency_checks , , , .
«».
then opcache.max_wasted_percentage . FPM. FPM, , .
.
OPCache
ã¯ããã«
, . OPCache . , ,
Zend . ,
, . «
». , .
, OPArray, , .
, , « PHP». ,
IS_VAR IS_CV ,
IS_CONST â
IS_TMP_VAR . , runtime, .
OPCache
IS_CONST . ( runtime); CGF- ( ) . . PHP: , . - , OPCache OPArray ( OPArray ), . PHP - â , : . , , , , . Java ++, «» - . PHP .
PHP . , , . - .
OPCache - . INI-
opcache.optimization_level . :
, PHP 5 , , , OPCache. PHP 7 .
äŸïŒ
if (false) { echo "foo"; } else { echo "bar"; }
:

:

,
if(false)
, Zend
ZEND_ECHO
. , . , runtime.
, , ( ).
IS_CONST IS_CV , :
if ($a) { echo "foo"; } else { echo "bar"; }
, PHP 5 PHP 7:
if (__DIR__ == '/tmp') { echo "foo"; } else { echo "bar"; }
PHP 7
__DIR__
, OPCache. OPCache. PHP 5.6
__DIR__
, . OPCache.
. PHP 5.6 PHP 7 OPCache, . , PHP 5.6 , PHP 7, PHP 5.6 , PHP 7 ( OPCache).
-
OPCache
IS_TMP_VAR IS_CONST . , . - , . :
function_exists()
is_callable()
, .extension_loaded()
, dl()
.defined()
constant()
, .dirname()
.strlen()
dirname()
- ( PHP 7).
:
if (function_exists('array_merge')) { echo 'yes'; }
, runtime:

:

, . , :
if function_exists('my_custom_function')) { }
, '__'. , PHP OPCache . :
function my_custom_function() { } if function_exists('my_custom_function')) { }
, ,
( ).
dirname()
( PHP 7):
if (dirname(__FILE__) == '/tmp') { echo 'yo'; }
:

:

strlen()
PHP 7 . , . äŸïŒ
if (strlen(dirname(__FILE__)) == 4) { echo "yes"; } else { echo "no"; }
:

:

, /, OPCache «» (, «» ).
(Transtyping)
OPCache
IS_CONST , , . runtime:
$a = 8; $c = $a + "42"; echo $c;
:

:

true-
ZEND_ADD
: .
ADD
. , runtime , , , . .
OPCache, :
if (ZEND_OPTIMIZER_PASS_2 & OPTIMIZATION_LEVEL) { zend_op *opline; zend_op *end = op_array->opcodes + op_array->last; opline = op_array->opcodes; while (opline < end) { switch (opline->opcode) { case ZEND_ADD: case ZEND_SUB: case ZEND_MUL: case ZEND_DIV: if (ZEND_OP1_TYPE(opline) == IS_CONST) { if (ZEND_OP1_LITERAL(opline).type == IS_STRING) { convert_scalar_to_number(&ZEND_OP1_LITERAL(opline) TSRMLS_CC); } } case ZEND_ASSIGN_ADD: case ZEND_ASSIGN_SUB: case ZEND_ASSIGN_MUL: case ZEND_ASSIGN_DIV: if (opline->extended_value != 0) { break; } if (ZEND_OP2_TYPE(opline) == IS_CONST) { if (ZEND_OP2_LITERAL(opline).type == IS_STRING) { convert_scalar_to_number(&ZEND_OP2_LITERAL(opline) TSRMLS_CC); } } break;
, PHP 7. , PHP 7 OPCache ( ), , PHP 5.
IS_CONST , . PHP 5 , OPCache:
$a = 4 + "33"; echo $a;
:

:

4 + 33
ZEND_ADD
, . runtime, . : PHP 7 , PHP 5 OPCache.
. , .
$i = "foo"; $i = $i + 42; echo $i;
:

:

Zend VM
ZEND_ASSIGN_ADD
ZEND_ADD
ZEND_ASSIGN
.
$i+=3;
ã
ZEND_ASSIGN_ADD
, ( , )
:
$j = 4; $j++; echo $j;
:

:

OPCache
++$i
$i++
, .
ZEND_POST_INC
â , , , ,
ZEND_PRE_INC
: , ( ). ,
ZEND_POST_INC
, ,
ZEND_FREE
. OPCache
ZEND_PRE_INC
ZEND_FREE
: runtime.
PHP-? , . , , . :
const FOO = "bar"; echo FOO;

:

. , , , runtime .
define()
const
, :
define('FOO', 'bar'); echo FOO;
:

:

define()
, , runtime, (
define()
). ããã¯éåžžã«æªãã§ãã
const
DECLARE_CONST
.
Zend .
(Multiple jump target resolution)
, . ( ). , , . â , . PHP- .
if
,
switch
,
while
,
try
,
foreach
,
?
: â . true, , â .
, . landing- , landing-. , «».
äŸïŒ
if ($a) { goto a; } else { echo "no"; } a: echo "a";
:

( ): « $a 0, 3, «no». 4, «a»».
- « 3, 4». « 4»? :

« $a , 2 «a», «no»». , ? , . ,
while
if
,
goto
,
switch
,
try-catches
, .. OPArray . , . ( ) . runtime.
ãããã«
. , « » (early returns). try-catch switch-break. PHP, .
, , . OPCache , , PHP , , ⊠, , . .
OPCache , PHP. PHP 7, . PHP 7 ( ) PHP 5 ( PHP 5 ).
, , . , . , , , . , , OPCache. : , . ( runtime).
çµãã
, OPCache - . , , . OPCache PHP, . PHP- , , . , â PHP-FPM SAPI.