ï¼2016/01/01 02:20追è¨ï¼mbstring.func_overloadã®ç« ãç大ã«æ¸ãæãã¾ããããªããå»æ¢ãããã¨æãè¾¼ãã§ããã§ãããç¹ã«å»æ¢ãããã¦ãªãã¦ãPHP 7ã§ãåããã¨ã¯åãã¾ãã
ï¼2017/5/14 追è¨ï¼PHP 7ã§mbstring.func_overloadãæå¹ã«ãã¦ãstrlen()ã¯æå¾ éãåä½ããªãã¨æ¸ãã¦ãã¾ããããæå¾ éãmb_strlen()ã¨ãã¦åä½ãã¦ãã¾ãããã¤ã¾ããã2016/01/01 02:20追è¨ããä¸é¨åã§ããã®ã§ãè¨äºãä¿®æ£ã»è¿½è¨ãã¾ããã
ã¿ãªãããããPHP 7ã¯è©¦ãã¦ã¿ã¾ãããï¼
PHP 7ã®ã»ã¼ã«ã¹ãã¤ã³ãã¨è¨ãã°é«éåã§ãããããã®é«éåã§ãããå人çã«ã¯ãããéãããä½å°ãã£ãã®ï¼ãã¨æãããããªç®æãé«éåããã¦ããããã¾ããæ¬ç¨¿ã§ã¯ãããããæå¤ãªé«éåãã¤ã³ãã®ä¸ã¤ã¨ãã¦strlen
é¢æ°ã«é¢ããé«éåã«ã¤ãã¦ç´¹ä»ãã¾ãã
strlené¢æ°ã¨æé©å
念ã®ãã説æãã¦ããã¾ãã¨ãstrlen
é¢æ°ã¨ããã®ã¯æååã®é·ããè¿ãé¢æ°ã§ããã¨ããã§ãPHPã§ã¯æååã®é·ãã¯ãããããæååæ¬ä½ã¨ã¯å¥ã«æ ¼ç´ããã¦ãã¾ãï¼PHPã®æååã¯ãã«æåã§ã¿ã¼ããã¼ãããã¦ããªãã®ã§ãæååé·ããªãã¨æååæ«å°¾ããããã¾ããï¼ãã¤ã¾ããå
ã
ããã£ã¦ããæ°åãè¿ãã ãã§ããããstrlen
é¢æ°èªä½ã¯å¤§ããä»äºã¯ãã¾ããã
大ããä»äºããã¦ããªãé¢æ°ãæé©åã®å¯¾è±¡ã«ãªãã¨ããã®ã¯å°ãä¸æè°ãªæ°ããã¾ãããããããããã§ã¯ããã¾ãããå®ã¯PHPã®é¢æ°å¼ã³åºãã¯ã³ã¹ããæ¯è¼çé«ãã®ã§ãé¢æ°å¼ã³åºãèªä½ãæé©åã®å¯¾è±¡ã«ãªã£ã¦ããã¨ãããããªã®ã§ãã
å®éã«ãPHP 7ã§ã¯é¢æ°å¼ã³åºãèªä½ã®ã³ã¹ããä¸ãããããªæé©åãè¡ããã¾ããï¼åèï¼ãPHP 7調査(16)高速な引数パーサの導入ãï¼ãããããstrlen
é¢æ°ã«ã¤ãã¦ã¯ãããããé¢æ°å¼ã³åºããããªããã¨ããæé©åãæ¡ç¨ããã¦ãã¾ãããªãã¨ãstrlen
é¢æ°ã¯é¢æ°å¼ã³åºãã§ã¯ãªãZend VMã®1å½ä»¤ã«æ ¼ä¸ãã«ãªã£ã¦ãã¾ãã
ãã®ãã¨ã確èªãã¦ã¿ã¾ããããvldæ¡å¼µã§strlen
é¢æ°ã®ã³ã³ãã¤ã«çµæã確èªãã¦ã¿ãã¨ãè¦æ
£ããªãSTRLEN
ã¨ããopcodeãè¦ã¤ããã¾ãã
$ php -dextension=vld.so -dvld.active=1 -r 'strlen($foo);' ï¼ç¥ï¼ line #* E I O op fetch ext return operands ------------------------------------------------------------------------------------- 1 0 E > STRLEN ~1 !0 1 FREE ~1 2 > RETURN null ï¼ç¥ï¼ $
è²´éãªopcodeããããªãã¨ã§1åæ¶è²»ãã¦ããã®ãï¼ä»ã®é¢æ°ã§ã¯åãæé©åãããªãã®ãï¼ã¨ããçåã湧ãã¦ãã¾ãããé »ç¹ã«å¼ã°ããå²ã«å¤§ãããã¨ããã¦ããªãæ°å°ãªãé¢æ°ã¨ãããã¨ãªã®ããããã¾ããã
対å¿ããCã½ã¼ã¹ã³ã¼ãã確èªãã
PHP 7ã®Zend/zend_compile.c
ãè¦ãã¨ã次ã®ããã«ä¸é¨ã®é¢æ°ãç¹å¥æ±ããã¦ããå¦çãè¦ã¤ããã¾ãã
int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc) /* {{{ */ { if (fbc->internal_function.handler == ZEND_FN(display_disabled_function)) { return FAILURE; } if (zend_string_equals_literal(lcname, "strlen")) { return zend_compile_func_strlen(result, args); } else if (zend_string_equals_literal(lcname, "is_null")) { return zend_compile_func_typecheck(result, args, IS_NULL); } else if (zend_string_equals_literal(lcname, "is_bool")) { return zend_compile_func_typecheck(result, args, _IS_BOOL); } else if (zend_string_equals_literal(lcname, "is_long") || zend_string_equals_literal(lcname, "is_int") || zend_string_equals_literal(lcname, "is_integer") ) { return zend_compile_func_typecheck(result, args, IS_LONG); } else if (zend_string_equals_literal(lcname, "is_float") || zend_string_equals_literal(lcname, "is_double") || zend_string_equals_literal(lcname, "is_real") ) { return zend_compile_func_typecheck(result, args, IS_DOUBLE); } else if (zend_string_equals_literal(lcname, "is_string")) { return zend_compile_func_typecheck(result, args, IS_STRING); } else if (zend_string_equals_literal(lcname, "is_array")) { return zend_compile_func_typecheck(result, args, IS_ARRAY); } else if (zend_string_equals_literal(lcname, "is_object")) { return zend_compile_func_typecheck(result, args, IS_OBJECT); } else if (zend_string_equals_literal(lcname, "is_resource")) { return zend_compile_func_typecheck(result, args, IS_RESOURCE); } else if (zend_string_equals_literal(lcname, "defined")) { return zend_compile_func_defined(result, args); } else if (zend_string_equals_literal(lcname, "call_user_func_array")) { return zend_compile_func_cufa(result, args, lcname); } else if (zend_string_equals_literal(lcname, "call_user_func")) { return zend_compile_func_cuf(result, args, lcname); } else if (zend_string_equals_literal(lcname, "assert")) { return zend_compile_assert(result, args, lcname, fbc); } else { return FAILURE; } } /* }}} */
ãããã«strlen
é¢æ°ã®ããã®åå²ãããã®ããããã¾ãã
ã¾ããstrlen
é¢æ°ä»¥å¤ã«ãis_long
é¢æ°ãªã©ãç¹å¥æ±ãããã¦ãããã¨ããããã¾ããå®ã¯ãããã®é¢æ°ãé¢æ°å¼ã³åºããè¡ããªããããªæé©åãè¡ããã¦ãã¾ãã
ã¾ããassert
é¢æ°ãç¹å¥æ±ãããã¦ãããã¨ããããã¾ããPHP 7ããassert
é¢æ°ã®å
å´ã«ä»»æã®å¼ãæ¸ããããã«ãªã£ãããã§ãããassert
ã®å¼æ°ãæ®éã®å¼æ°ã¨åãããã«è©ä¾¡ããããã«ã¯ãããªãã®ã§ãå¼ã¨ãã¦ä¿åãããããªå¦çããã¦ããã ãããã¨æ³åãã¤ãããããããã§ãã
strlené¢æ°ã®æé©åã¨mbstring.func_overloadã®é¢ä¿
ï¼ããããªããããã®ç« ã¯æãè¾¼ã¿ã§æ¸ãã¦ããã®ã§å ¨é¢çã«æ¸ãæãã¾ããâ¦ï¼
PHPã«ã¯mbstring.func_overload
ãæå®ãããã¨ã§substr
é¢æ°ã®å¼ã³åºãã«å¯¾ãã¦mb_substr
é¢æ°ãå¼ã°ãããããªæ©è½ãããã¾ãããã«ããã¤ãé対å¿ã®PHPã¢ããªã±ã¼ã·ã§ã³ãç¡çç¢çãã«ããã¤ã対å¿ã«ããããã®å¤§æã®ããã¯ãªãã ã¨æãã¾ãã
ã¨ããã§ããã®æ©è½ã¯ä»åç´¹ä»ããæé©åã¨å¯æ¥ãªé¢ä¿ãããã¾ããã¨ããã®ããstrlen
ãmbstringé¢æ°ã¸ã®ç½®ãæã対象ã ããã§ãããã®æ©è½ã¯é¢æ°ãã¼ãã«ã®ç½®ãæãã«ããå®ç¾ããã¦ããã®ã§ãããä»åã®ããã«å¥opcodeã«ã³ã³ãã¤ã«ããã¦ãã¾ãã¨å½ç¶é¢æ°å¼ã³åºãã¯è¡ãããªããããé¢æ°ã®æåãå¤æ´ã§ãã¾ããã
ããã§ãPHP 7ã§ã¯mbstring.func_overload
ãè¨å®ããã¦ããå ´åã«ã¯strlen
ã®opcodeåã¯è¡ããããå¾æ¥éãé¢æ°å¼ã³åºãã®å½¢ã§ã³ã³ãã¤ã«ããã¾ããã¤ã¾ããæå¾
éãmb_strlen
ãå¼ã³åºããããã¨ã«ãªãã¾ãã