ます’s Blog - どうでもいい記事100選

どうでもいい記事100選

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)

ネタなので本気にしないでね(ぉ