zend.ze1_compatibility_mode
・strrpos()とstrripos()は、needleとして文字列全体を使用するようになりました。
・array_merge()は、配列のみを指定できるよう変更されました。配列以外の変数を指定した場合は、各パラメータ毎にE_WARNINGが発生します。あなたのコードで突然E_WARNINGが発生し始める可能性があるため注意してください。
・get_class(),get_parent_class()およびget_class_methods()は、ケース依存(大文字小文字を区別)で宣言時に使用されたクラス/メソッドの名前を返すようになっていますこれにより、以前の動作(クラス名は小文字で返される)に依存している古いスクリプトでは問題を発生する可能性があります。解決策としては、全てのスクリプトでこれらの関数を検索し、strtolower()を使用するというものが考えられます。このケース依存性に関する変更は、自動的に定義される定数__CLASS__,__METHOD__,および__FUNCTION__にも適用されます。これらの値は、宣言時と同様に(ケース依存で)返されます。
strripos関数はPHP5から利用可能なのですが、それはさておき。
__FUNCTION__ 関数名(PHP4.3.0で追加されました)。PHP5以降、この定数は宣言時の関数名(ケース依存)を返します。PHP4では、この値は常に小文字で返されました。
__CLASS__ クラス名(PHP4.3.0で追加されました)。PHP5以降、この定数は宣言時のクラス名(ケース依存)を返します。PHP4では、この値は常に小文字で返されました。
ふむ。
zend.ze1_compatibility_mode boolean
ZendEngine1(PHP4)との互換モードを有効にします。
この設定は、オブジェクトのコピー、キャスト(プロパティを保持しないオブジェクトがFALSEあるいは0のいずれになるか)、そして比較に影響を与えます。
このモードの場合、オブジェクトを渡す際のデフォルトの方法は、参照渡しではなく値渡しとなります。
なる程。
zend.ze1_compatibility_modeディレクティブを有効にしてもオブジェクト周りの挙動がPHP4と同様になるだけです。
どうせなら。。。という事で、zend.ze1_compatibility_modeディレクティブを有効することで上に掲載されている挙動の変更点を元に戻す(PHP4と同じになる)ようにしてみました。
error_reportingディレクティブにE_STRICTを含めていると警告を発生させるようにしています。
--- php-5.2.5,orig/ext/standard/array.c 2007-11-06 22:28:21.000000000 +0900 +++ php-5.2.5/ext/standard/array.c 2007-12-07 19:08:12.000000000 +0900 @@ -2369,8 +2369,12 @@ for (i = 0; i < argc; i++) { if (Z_TYPE_PP(args[i]) != IS_ARRAY) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i+1); - params_ok = 0; + if(!EG(ze1_compatibility_mode)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i+1); + params_ok = 0; + } else { + php_error_docref(NULL TSRMLS_CC, E_STRICT, "Argument #%d is not an array", i+1); + } } } if (params_ok == 0) { --- php-5.2.5,orig/ext/standard/string.c 2007-10-04 22:31:11.000000000 +0900 +++ php-5.2.5/ext/standard/string.c 2007-12-07 19:08:12.000000000 +0900 @@ -1780,6 +1780,20 @@ RETURN_FALSE; } + if(EG(ze1_compatibility_mode)) { + char *found = NULL; + + php_error_docref(NULL TSRMLS_CC, E_STRICT, "The needle may be a string of more than one character as of PHP 5.0.0."); + + found = strrchr(haystack, needle[0]); + + if (found) { + RETURN_LONG(haystack_len - strlen(found)); + } else { + RETURN_FALSE; + } + } + if (offset >= 0) { if (offset > haystack_len) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Offset is greater than the length of haystack string"); --- php-5.2.5,orig/Zend/zend_builtin_functions.c 2007-08-30 16:43:21.000000000 +0900 +++ php-5.2.5/Zend/zend_builtin_functions.c 2007-12-07 19:08:12.000000000 +0900 @@ -564,6 +564,11 @@ if (!ZEND_NUM_ARGS()) { if (EG(scope)) { + if(EG(ze1_compatibility_mode)) { + zend_error(E_STRICT, "The class name '%s' is returned in it's original notation of PHP 5.0.0.", EG(scope)->name); + zend_str_tolower(EG(scope)->name, EG(scope)->name_length); + } + RETURN_STRINGL(EG(scope)->name, EG(scope)->name_length, 1); } else { zend_error(E_WARNING, "get_class() called without object from outside a class"); @@ -579,6 +584,11 @@ dup = zend_get_object_classname(*arg, &name, &name_len TSRMLS_CC); + if(EG(ze1_compatibility_mode)) { + zend_error(E_STRICT, "The class name '%s' is returned in it's original notation of PHP 5.0.0.", name); + zend_str_tolower(name, name_len); + } + RETURN_STRINGL(name, name_len, dup); } /* }}} */ @@ -596,6 +606,11 @@ if (!ZEND_NUM_ARGS()) { ce = EG(scope); if (ce && ce->parent) { + if(EG(ze1_compatibility_mode)) { + zend_error(E_STRICT, "The class name '%s' is returned in it's original notation of PHP 5.0.0.", ce->parent->name); + zend_str_tolower(ce->parent->name, ce->parent->name_length); + } + RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1); } else { RETURN_FALSE; @@ -608,6 +623,11 @@ if (Z_TYPE_PP(arg) == IS_OBJECT) { if (Z_OBJ_HT_PP(arg)->get_class_name && Z_OBJ_HT_PP(arg)->get_class_name(*arg, &name, &name_length, 1 TSRMLS_CC) == SUCCESS) { + if(EG(ze1_compatibility_mode)) { + zend_error(E_STRICT, "The class name '%s' is returned in it's original notation of PHP 5.0.0.", name); + zend_str_tolower(name, name_length); + } + RETURN_STRINGL(name, name_length, 0); } else { ce = zend_get_class_entry(*arg TSRMLS_CC); @@ -621,6 +641,11 @@ } if (ce && ce->parent) { + if(EG(ze1_compatibility_mode)) { + zend_error(E_STRICT, "The class name '%s' is returned in it's original notation of PHP 5.0.0.", ce->parent->name); + zend_str_tolower(ce->parent->name, ce->parent->name_length); + } + RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1); } else { RETURN_FALSE; @@ -882,6 +907,12 @@ zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0) { MAKE_STD_ZVAL(method_name); + + if(EG(ze1_compatibility_mode)) { + zend_error(E_STRICT, "This function name '%s' returns the name of the methods as they were declared(case-sensitive) of PHP 5.0.0.", mptr->common.function_name); + zend_str_tolower(mptr->common.function_name, len); + } + ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1); zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL); } --- php-5.2.5,orig/Zend/zend_language_scanner.l 2007-09-10 01:33:34.000000000 +0900 +++ php-5.2.5/Zend/zend_language_scanner.l 2007-12-07 20:18:17.000000000 +0900 @@ -1484,6 +1484,12 @@ } zendlval->value.str.len = strlen(class_name); zendlval->value.str.val = estrndup(class_name, zendlval->value.str.len); + + if(EG(ze1_compatibility_mode)) { + zend_error(E_STRICT, "The class name '%s' returns the class name as it was declared (case-sensitive) of PHP 5.0.0.", zendlval->value.str.val); + zend_str_tolower(zendlval->value.str.val, zendlval->value.str.len); + } + zendlval->type = IS_STRING; return T_CLASS_C; } @@ -1500,6 +1506,12 @@ } zendlval->value.str.len = strlen(func_name); zendlval->value.str.val = estrndup(func_name, zendlval->value.str.len); + + if(EG(ze1_compatibility_mode)) { + zend_error(E_STRICT, "The function name '%s' returns the function name as it was declared (case-sensitive) of PHP 5.0.0.", zendlval->value.str.val); + zend_str_tolower(zendlval->value.str.val, zendlval->value.str.len); + } + zendlval->type = IS_STRING; return T_FUNC_C; }
このパッチを適用する事で以下の結果になりました。わーい。
% cat /path/to/ze1_compatibility_mode.php <?php class bar { var $message; } $obj1 = new bar; $obj2 = $obj1; $obj3 = $obj2; $obj1->message = "go\n"; $obj2->message = "to\n"; $obj3->message = "heaven\n"; echo $obj1->message; echo $obj2->message; echo $obj3->message; class Hoge { function Go1( ) { var_dump( __CLASS__ ); var_dump( __FUNCTION__ ); var_dump( get_class( ) ); var_dump( get_parent_class( ) ); } } class Huga extends Hoge { function Go2( ) { var_dump( __CLASS__ ); var_dump( __FUNCTION__ ); var_dump( get_class( ) ); var_dump( get_parent_class( ) ); } } function Boo( ) { var_dump( __FUNCTION__ ); } $obj1 = new Huga; $obj2 = new Huga; echo "------------------------------------------------------\n"; var_dump( get_class( $obj1 ) ); var_dump( get_parent_class( $obj1 ) ); echo "------------------------------------------------------\n"; var_dump( get_class( $obj2 ) ); var_dump( get_parent_class( $obj2 ) ); echo "------------------------------------------------------\n"; $obj1->Go1( ); echo "------------------------------------------------------\n"; $obj2->Go2( ); echo "------------------------------------------------------\n"; Boo( ); echo "------------------------------------------------------\n"; var_dump( get_class_methods( "Huga" ) ); echo "------------------------------------------------------\n"; var_dump( array_merge( 1, 2, 3 ) ); $haystack = "ABCDEFG"; $needle = "GREAT!"; echo "------------------------------------------------------\n"; var_dump( strrpos( $haystack, $needle ) ); ?> % /path/to/php-4.4.7 -d error_reporting='E_ALL' /path/to/ze1_compatibility_mode.php go to heaven ------------------------------------------------------ string(4) "huga" string(4) "hoge" ------------------------------------------------------ string(4) "huga" string(4) "hoge" ------------------------------------------------------ string(4) "hoge" string(3) "go1" NULL NULL ------------------------------------------------------ string(4) "huga" string(3) "go2" NULL NULL ------------------------------------------------------ string(3) "boo" ------------------------------------------------------ array(2) { [0]=> string(3) "go1" [1]=> string(3) "go2" } ------------------------------------------------------ array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } ------------------------------------------------------ int(6) % /path/to/php-5.2.5 -d error_reporting='E_ALL' /path/to/ze1_compatibility_mode.php heaven heaven heaven ------------------------------------------------------ string(4) "Huga" string(4) "Hoge" ------------------------------------------------------ string(4) "Huga" string(4) "Hoge" ------------------------------------------------------ string(4) "Hoge" string(3) "Go1" string(4) "Hoge" bool(false) ------------------------------------------------------ string(4) "Huga" string(3) "Go2" string(4) "Huga" string(4) "Hoge" ------------------------------------------------------ string(3) "Boo" ------------------------------------------------------ array(2) { [0]=> string(3) "Go2" [1]=> string(3) "Go1" } ------------------------------------------------------ Warning: array_merge(): Argument #1 is not an array in /path/to/ze1_compatibility_mode.php on line 69 Warning: array_merge(): Argument #2 is not an array in /path/to/ze1_compatibility_mode.php on line 69 Warning: array_merge(): Argument #3 is not an array in /path/to/ze1_compatibility_mode.php on line 69 NULL ------------------------------------------------------ bool(false) % /path/to/php-5.2.5 -d error_reporting='E_ALL' -d zend.ze1_compatibility_mode='On' /path/to/ze1_compatibility_mode.php go to heaven ------------------------------------------------------ string(4) "huga" string(4) "hoge" ------------------------------------------------------ string(4) "huga" string(4) "hoge" ------------------------------------------------------ string(4) "hoge" string(3) "go1" string(4) "hoge" bool(false) ------------------------------------------------------ string(4) "huga" string(3) "go2" string(4) "huga" string(4) "hoge" ------------------------------------------------------ string(3) "boo" ------------------------------------------------------ array(2) { [0]=> string(3) "go2" [1]=> string(3) "go1" } ------------------------------------------------------ array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } ------------------------------------------------------ int(6) % /path/to/php-5.2.5 -d error_reporting='E_ALL|E_STRICT' -d zend.ze1_compatibility_mode='On' /path/to/ze1_compatibility_mode.php Strict Standards: The class name 'Hoge' returns the class name as it was declared (case-sensitive) of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 24 Strict Standards: The function name 'Go1' returns the function name as it was declared (case-sensitive) of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 25 Strict Standards: The class name 'Huga' returns the class name as it was declared (case-sensitive) of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 35 Strict Standards: The function name 'Go2' returns the function name as it was declared (case-sensitive) of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 36 Strict Standards: The function name 'Boo' returns the function name as it was declared (case-sensitive) of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 44 Strict Standards: Implicit cloning object of class 'bar' because of 'zend.ze1_compatibility_mode' in /path/to/ze1_compatibility_mode.php on line 8 Strict Standards: Implicit cloning object of class 'bar' because of 'zend.ze1_compatibility_mode' in /path/to/ze1_compatibility_mode.php on line 9 Strict Standards: Implicit cloning object of class 'bar' because of 'zend.ze1_compatibility_mode' in /path/to/ze1_compatibility_mode.php on line 10 go to heaven Strict Standards: Implicit cloning object of class 'Huga' because of 'zend.ze1_compatibility_mode' in /path/to/ze1_compatibility_mode.php on line 47 Strict Standards: Implicit cloning object of class 'Huga' because of 'zend.ze1_compatibility_mode' in /path/to/ze1_compatibility_mode.php on line 48 ------------------------------------------------------ Strict Standards: The class name 'Huga' is returned in it's original notation of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 51 string(4) "huga" Strict Standards: The class name 'Hoge' is returned in it's original notation of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 52 string(4) "hoge" ------------------------------------------------------ Strict Standards: The class name 'Huga' is returned in it's original notation of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 55 string(4) "huga" Strict Standards: The class name 'Hoge' is returned in it's original notation of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 56 string(4) "hoge" ------------------------------------------------------ string(4) "hoge" string(3) "go1" Strict Standards: The class name 'Hoge' is returned in it's original notation of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 26 string(4) "hoge" bool(false) ------------------------------------------------------ string(4) "huga" string(3) "go2" Strict Standards: The class name 'Huga' is returned in it's original notation of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 37 string(4) "huga" Strict Standards: The class name 'hoge' is returned in it's original notation of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 38 string(4) "hoge" ------------------------------------------------------ string(3) "boo" ------------------------------------------------------ Strict Standards: This function name 'Go2' returns the name of the methods as they were declared(case-sensitive) of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 66 Strict Standards: This function name 'Go1' returns the name of the methods as they were declared(case-sensitive) of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 66 array(2) { [0]=> string(3) "go2" [1]=> string(3) "go1" } ------------------------------------------------------ Strict Standards: array_merge(): Argument #1 is not an array in /path/to/ze1_compatibility_mode.php on line 69 Strict Standards: array_merge(): Argument #2 is not an array in /path/to/ze1_compatibility_mode.php on line 69 Strict Standards: array_merge(): Argument #3 is not an array in /path/to/ze1_compatibility_mode.php on line 69 array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } ------------------------------------------------------ Strict Standards: strrpos(): The needle may be a string of more than one character as of PHP 5.0.0. in /path/to/ze1_compatibility_mode.php on line 75 int(6)
ネタなので本気にしないでね(ぉ