1. 程式人生 > >php5.2 、5.3、5.4、5.5、5.6 各個版本升級不相容點

php5.2 、5.3、5.4、5.5、5.6 各個版本升級不相容點

最近工作中將php5.2升級到php5.6,在升級的過程中,需要對php各個版本之間的不相容的問題進行討論和測試論證。依據php版本不相容 分支說明 , 分別在多個版本之間進行了測試,分享如下:

php5.3 不相容5.2

1.在 PHP 5.3.x 的所有繫結擴充套件中應用了新的內部引數解析API, 當給函式傳遞了不相容的引數時將返回 NULL. 但有一些例外,比如函式 get_class() 在出現錯誤時將會返回 FALSE.

解讀:這裡其實是,php5.3對函式的引數型別相比於php5.2有更強的校驗了。比如:引數的型別定義是 int,你傳 string,php5.2不報錯,php5.3就會報錯了。例子如下:

string str_pad ( string $input , int $pad_length [, string $pad_string = " " [, int $pad_type = STR_PAD_RIGHT ]] )

echo str_pad('125', 'p6ll', 0, STR_PAD_LEFT);

php5.3:

      PHP Warning:  str_pad() expects parameter 2 to be long, string given in Command line code on line 1

php5.2:

      125

2. clearstatcache() 預設不再清除快取的 realpath

php5.3中的函式api是:

      void clearstatcache ([ bool $clear_realpath_cache = false [, string $filename ]] )

php5.2中的函式api是:

      void clearstatcache ([ bool $clear_realpath_cache = true [, string $filename ]] ) 

這個函式的意義是清除file的快取,有一些函式會帶來file的快取,比如is_file ,file_exists等。不刪除路徑的話,在使用的過程中,就要考慮檔案是否存在了,因為檔案在使用的過程中,可能會刪除的。

3.realpath() 現在是完全與平臺無關的. 結果是非法的相對路徑比如 __FILE__ . "/../x" 將不會工作.

解讀:realpath在不同的版本,得到的路徑是不一樣的。例子如下:

chdir('/tmp/test/');
echo realpath('./');

php5.3:執行目錄:/data/website/qqtalkweb/htdocs/syb

結果: /tmp/test

php5.2:執行目錄:/root

結果: /root

4. call_user_func() 系列函式即使被呼叫者是一個父類也使用 $this.

解讀:這個call_user_func 和 call_user_func_array 序列函式呼叫時,被呼叫者即使是一個父類也是使用$this。

5.陣列函式 natsort(), natcasesort(), usort(), uasort(), uksort(), array_flip(), 和 array_unique() 將不再接受物件作為引數. 在將這些函式應用於物件時, 請首先將物件轉換為陣列.

解讀:這個很好理解,就是這些函式不接受物件的引數,如果是物件,請先將引數轉換為陣列。

6.按引用傳遞引數的函式在被按值傳遞呼叫時行為發生改變。 此前函式將接受按值傳遞的引數, 現在將丟擲致命錯誤。之前任何期待傳遞引用但是在呼叫時傳遞了常量或者字面值 的函式, 需要在呼叫前改為將該值賦給一個變數。

解讀:這個按照字面意思理解就好了

7.新的 mysqlnd 庫需要使用 MySQL 4.1 新的 41 位元組密碼格式。繼續使用舊的 16 位元組密碼將導致 mysql_connect() 和其它類似函式 丟擲 "mysqlnd cannot connect to MySQL 4.1+ using old authentication." 錯誤。

解讀:字面理解就好

8.新的 mysqlnd 庫將不再讀取 MySQL 配置檔案(my.cnf/my.ini), 這與舊版本的 libmysql 庫不同. 如果你的程式碼依賴於這些配置 檔案, 你可以使用 mysqli_options() 顯式地載入它。注意, 這意味著如果 PDO 中的 MySQL 支援使用了 mysqlnd 進行編譯,PDO 特有常量 PDO::MYSQL_ATTR_READ_DEFAULT_FILE 和PDO::MYSQL_ATTR_READ_DEFAULT_GROUP 將是未定義的。

解讀:這個多說一句,php5.3後,php自帶了mysql的驅動,解決了php和mysql的多個license的問題。使用mysqlnd 作為的php  mysql,mysqli,pdo的驅動的話,需要顯式來定義。比如:--with-mysql=shared,mysqlnd --with-mysqli=shared,mysqlnd --with-pdo-mysql=shared,mysqlnd  ,在編譯php的是,需要這樣來定義 options。這樣的話,就不需要mysql的配置檔案 my.ini 了,並且不再使用 libmysql 作為php連線mysql的驅動

9.SplFileInfo 及其相關目錄類會移除末尾的 /.

解讀:這個直接從字面意思理解就好了。

10. __toString 魔術方法不再接受引數.

解讀:從字面意思來解讀

11.魔術方法 __get, __set, __isset, __unset, and __call 應該總是公共的(public)且不能是靜態的(static). 方法簽名是必須的。

解讀:從字面意思來解讀

12.現在 __call 魔術方法在訪問私有的(private)和被保護的(protected)方法時被呼叫

解讀:從字面意思來解讀

13.函式內 include 或者 require 一個檔案時,檔案內 將不能使用 func_get_arg(), func_get_args() 和 func_num_args() 函式。

解讀:從字面意思來解讀

14.新增了一個包裹在 MHASH 擴充套件外面的模擬層。但是並非所有的演算法都涉及到了,值得注意的是 s2k 雜湊演算法。這意味著 s2k 雜湊演算法在 PHP 5.3.0 中不再可用。

解讀:從字面意思來解讀。另外這個用得很少的

php5.4 不相容5.3

1. 不再支援 安全模式 。任何依賴安全模式的應用在安全方面都需要進行調整。

解讀:安全模式 在5.3中引入,在5.4就被刪除了,說明有很大的缺陷。試圖幫php解決共享伺服器的問題。從php方面去解決作業系統方面的問題,不現實。具體請參考官方說明  安全模式 

2.移除 魔術引號 。為避免出現安全問題,依賴此特性的應用可能需要升級。 get_magic_quotes_gpc() 和 get_magic_quotes_runtime() 現在總是返回 FALSE 。呼叫 set_magic_quotes_runtime() 將產生一個 E_CORE_ERROR 級別的錯誤。
當開啟時,所有的 '(單引號),"(雙引號),\(反斜線)和 NULL 字元都會被自動加上一個反斜線進行轉義。這和 addslashes() 作用完全相同。

解讀:這個是php有一個魔術引號的配置,如果我配置成功的話,會將 '(單引號),"(雙引號),\(反斜線)和 NULL 字元  自動加收昂一個反斜線來轉義。但是這樣會增加很多額外的操作,使得開發者不方便操作原始資料。5.4移除了這個功能。主要影響的函式是:magic_quotes_gpc,magic_quotes_runtime,magic_quotes_sybase 魔術引號

3.register_globals 和 register_long_arrays php.ini 指令被移除。

解讀:

register_globals 和 register_long_arrays都是php.ini 中的一個配置。
register_globals 可設定為ON和Off
1:當register_globals=Off
接收資料的程式應該用根據表單form傳值的方法來決定。GET:用$_GET['name']、$HTTP_GET_VARS['name']來接收值;POST:當form用POST提交資料$_POST['name']、$HTTP_POST_VARS['name']來接收值;
2:當register_globals=On
接收資料的程式可以直接使用$user_name和$user_pass的這種類似訪問變數的方式得到值。register_long_arrays 是來設定 標識 $HTTP_*_VARS 這類的變數(On) 
由於$HTTP_*_VARS這種變數已經過時,PHP手冊中明確表示反對使用,因此如果程式中還有這類變數建議更改為新的PHP 超全域性變數。
$HTTP_GET_VARS -> $_GET
$HTTP_POST_VARS -> $_POST
$HTTP_COOKIE_VARS -> $_COOKIE
$HTTP_POST_FILES -> $_POST

4.呼叫時的引用傳遞 被移除。

解讀:php之前如果方法定義了一個傳引用的引數,在呼叫時是可以傳 &的,但在5.4,這種傳參的方式就被移除了。例如:

function foo(&$var)
{
    $var++;
}
$a=5;
foo($a);// $a is 6 here
不需要這樣呼叫 foo(&$a);

5.break 和 continue 語句不再接受可變引數( 比如: break 1 + foo() * $bar; )。

解讀:從字面意思來解讀。一個例子說下:

像類似 break 2; 這樣的固定引數仍可使用。受此變化影響,不再允許出現 break 0; 和 continue 0; 。

6.在 日期與時間擴充套件 中,不再支援時區使用 TZ(TimeZone)環境變數設定。必須使用 date.timezone php.ini 配置選項或 date_default_timezone_set() 函式來指定時區。PHP 將不再嘗試猜測時區,而是回退到“UTC”併發出一條 E_WARNING 錯誤。

解讀:這個是關於時間的,從字面意思來理解就好了。

7.非數字的字串偏移量,比如 $a['foo'] 此處 $a 是一個字串,現在使用 isset() 時返回 false,使用 empty() 時返回 true,併產生一條 E_WARNING 錯誤。偏移量型別是布林和 null 則產生一條 E_NOTICE 錯誤。 數字字串(比如 $a['2'] )仍像以前一樣執行。注意像類似 '12.3' 和 '5 foobar' 這樣的偏移量將被視為非數字併產生一條 E_WARNING 錯誤,但因為向後相容的原因它們會被分別轉換成 12 和 5 。

解讀:下列程式碼返回不同的結果。 $str='abc';var_dump(isset($str['x'])); // 在 PHP 5.4 或更新版本返回 false,但在 PHP 5.3 或更低版本返回 true

8.陣列轉換成字串將產生一條 E_NOTICE 級別的錯誤,但返回的結果仍是字串 "Array" 。

解讀:其實就是陣列不能轉換為字串了。

9.NULL 、FALSE 、或 一個空字串被新增成一個物件的屬性時將發出一條 E_WARNING 級別的錯誤,而不是 E_STRICT 。

解讀:這個意思是放鬆了對 null 等的物件屬性的限制

10.現在引數名使用全域性變數將會導致一個致命錯誤。禁止類似 function foo($_GET, $_POST) {} 這樣的程式碼。

解讀:其實不能使用全域性的函式名來做函式的引數

11.Salsa10 和 Salsa20 雜湊演算法 被移除。

解讀:去掉了5.3支援的雜湊演算法

12.當使用兩個空陣列作為引數時, array_combine() 現在返回 array() 而不是 FALSE 。

解讀:這個我覺得其實php5.4對5.3的bug修復

13.htmlentities() 將像 htmlspecialchars() 一樣處理亞洲字符集,這是以前 PHP 版本的處理情況,但現在將會發出一條 E_STRICT 錯誤。

解讀:從字面理解就好了

14.強烈建議不要再使用 eregi() ,此特性在最新版本中被移除。

解讀:eregi 系列函式是一些匹配正則表示式用的。在5.4中將不再支援,請使用新的方式。

php5.5 不相容5.4

1.不再支援 Windows XP 和 2003

解讀:這個很簡單,xp 和 2003 已經進入歷史的長河了,新的版本沒有花大力氣去支援他了。

2.pack() 和 unpack() 函式的變化

pack() 現在支援“Z”格式程式碼,其表現的行為與“a”相同。unpack() now support the "Z" format code for NULL padded strings, and behaves as "a" did in previous versions: it will strip trailing NULL bytes.
支援null填充的z的格式,且其行為類似上一個版本中的“a”:清除後面的 NULL 位元組。
unpack() now keeps trailing NULL bytes when the "a" format code is used. 當使用a格式的時候,會保留後面的 NULL位元組
unpack() now strips all trailing ASCII whitespace when the "A" format code is used. 當使用A格式的時候,會清除最後的所有的ASCII空格字元

3.移除 PHP logo GUIDs

解讀:其實主要刪除了一些guid的函式,主要是以下的一些函式:

php_logo_guid() 此函式能夠返回用於顯示 PHP logo 內建影象的 ID
php_egg_logo_guid()
php_real_logo_guid()
zend_logo_guid()

php5.6 不相容5.5

1.使用陣列識別符號為類定義陣列型別的屬性時,陣列的鍵不會被覆蓋

解讀:在 PHP 5.6 之前的版本中,為類定義陣列型別的屬性時, 如果陣列中同時使用了顯式陣列鍵和隱式陣列鍵,並且顯式的鍵和隱式的序列鍵相同, 那麼陣列的鍵將被覆蓋。例如:

<?php
class C {
const ONE = 1;
public $array = [
self::ONE => 'foo',
'bar',
'quux',
];
}
var_dump((new C)->array);
?>

結果如下:
5.5:
array(2) {
[0]=>
string(3) "bar"
[1]=>
string(4) "quux"
}
5.6:
array(3) {
[1]=>
string(3) "foo"
[2]=>
string(3) "bar"
[3]=>
string(4) "quux"
}

2. 嚴格的 json_decode()

對於 JSON 字面量 true,false 和 null,如果不採用小寫格式,將會被 json_decode() 函式拒絕, 同時相應的設定 json_last_error()。 在之前的版本中,json_decode() 函式可以接受這些字面量的 全部大寫或者大小寫混寫的格式。

此變更僅會影響傳入到 json_decode() 中的 JSON 格式無效的情況, 有效的 JSON 輸入不會受到影響並且能夠正確解析。

3.當使用 SSL/TLS 的時候,流封裝器預設驗證端點證書和主機名

4.GMP 資源現為物件

GMP 資源現為物件。 GMP 擴充套件中的基於函式的 API 實現不受影響, 只有在程式碼中使用 is_resource() 或類似函式 來顯示檢測是否資源型別的程式碼才會受到影響。

5.Mcrypt 函式需要有效長度的金鑰和初始向量

mcrypt_encrypt(),mcrypt_decrypt(), mcrypt_cbc(),mcrypt_cfb(), mcrypt_ecb(),mcrypt_generic() 以及 mcrypt_ofb() 函式不再接受無效長度的金鑰和初始向量, 對於需要初始向量的分組加密模式,如果不提供初始向量,函式呼叫將會失敗。

6.cURL 檔案上傳

必須先設定 CURLOPT_SAFE_UPLOAD 為 FALSE 才能夠使用 @file 語法來上傳檔案。 建議使用 CURLFile 類來上傳檔案。

以上就是從php5.2升級到php5.3,5.4,5.5,5.6需要注意事項。