男女疯狂一边摸一边做羞羞视频|啊好深好硬快点用力别停动态图|亚洲一区无码中文字幕|特级无码毛片免费视频播放▽|久久狠狠躁免费观看|国内精品久久久久久网站

不向后兼容的變更

錯誤和異常處理相關(guān)的變更

在 PHP 7 中,很多致命錯誤以及可恢復的致命錯誤,都被轉換為異常來(lái)處理了。 這些異常繼承自 Error 類(lèi),此類(lèi)實(shí)現了 Throwable 接口 (所有異常都實(shí)現了這個(gè)基礎接口)。

這也意味著(zhù),當發(fā)生錯誤的時(shí)候,以前代碼中的一些錯誤處理的代碼將無(wú)法被觸發(fā)。 因為在 PHP 7 版本中,已經(jīng)使用拋出異常的錯誤處理機制了。 (如果代碼中沒(méi)有捕獲 Error 異常,那么會(huì )引發(fā)致命錯誤)。

PHP 7 中的錯誤處理的更完整的描述,請參見(jiàn) PHP 7 錯誤處理。 本遷移指導主要是列出對兼容性有影響的變更。

set_exception_handler() 不再保證收到的一定是 Exception 對象

拋出 Error 對象時(shí),如果 set_exception_handler() 里的異常處理代碼聲明了類(lèi)型 Exception ,將會(huì )導致 fatal error。

想要異常處理器同時(shí)支持 PHP5 和 PHP7,應該刪掉異常處理器里的類(lèi)型聲明。如果代碼僅僅是升級到 PHP7,則可以把類(lèi)型 Exception 替換成 Throwable。

<?php
// PHP 5 時(shí)代的代碼將會(huì )出現問(wèn)題
function handler(Exception $e) { ... }
set_exception_handler('handler');

// 兼容 PHP 5 和 7
function handler($e) { ... }

// 僅支持 PHP 7
function handler(Throwable $e) { ... }
?>

當內部構造器失敗的時(shí)候,總是拋出異常

在之前版本中,如果內部類(lèi)的構造器出錯,會(huì )返回 null 或者一個(gè)不可用的對象。 從 PHP 7 開(kāi)始,如果內部類(lèi)構造器發(fā)生錯誤, 那么會(huì )拋出異常。

解析錯誤會(huì )拋出 ParseError 異常

解析錯誤會(huì )拋出 ParseError 異常。 對于 eval() 函數,需要將其包含到一個(gè) catch 代碼塊中來(lái)處理解析錯誤。

E_STRICT 警告級別變更

原有的 E_STRICT 警告都被遷移到其他級別。 E_STRICT 常量會(huì )被保留,所以調用 error_reporting(E_ALL|E_STRICT) 不會(huì )引發(fā)錯誤。

E_STRICT 警告級別變更
場(chǎng)景 新的級別/行為
將資源類(lèi)型的變量用作鍵來(lái)進(jìn)行索引 E_NOTICE
抽象靜態(tài)方法 不再警告,會(huì )引發(fā)錯誤
重復定義構造器函數 不再警告,會(huì )引發(fā)錯誤
在繼承的時(shí)候,方法簽名不匹配 E_WARNING
在兩個(gè) trait 中包含相同的(兼容的)屬性 不再警告,會(huì )引發(fā)錯誤
以非靜態(tài)調用的方式訪(fǎng)問(wèn)靜態(tài)屬性 E_NOTICE
變量應該以引用的方式賦值 E_NOTICE
變量應該以引用的方式傳遞(到函數參數中) E_NOTICE
以靜態(tài)方式調用實(shí)例方法 E_DEPRECATED

關(guān)于變量處理的變化

PHP 7 現在使用了抽象語(yǔ)法樹(shù)來(lái)解析源代碼。這使得許多由于之前的PHP的解釋器的限制所不可能實(shí)現的改進(jìn)得以實(shí)現。 但出于一致性的原因導致了一些特殊例子的變動(dòng),而這些變動(dòng)打破了向后兼容。 在這一章中將詳細介紹這些例子。

關(guān)于間接使用變量、屬性和方法的變化

對變量、屬性和方法的間接調用現在將嚴格遵循從左到右的順序來(lái)解析,而不是之前的混雜著(zhù)幾個(gè)特殊案例的情況。 下面這張表說(shuō)明了這個(gè)解析順序的變化。

間接調用的表達式的新舊解析順序
表達式 PHP 5 的解析方式 PHP 7 的解析方式
$$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz']
$foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz']
$foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']()
Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']()

使用了舊的從右到左的解析順序的代碼必須被重寫(xiě),明確的使用大括號來(lái)表明順序(參見(jiàn)上表中間一列)。 這樣使得代碼既保持了與PHP 7.x的前向兼容性,又保持了與PHP 5.x的后向兼容性。

這同樣影響了 global 關(guān)鍵字。如果需要的話(huà)可以使用大括號來(lái)模擬之前的行為。

<?php
function f() {
    
// Valid in PHP 5 only.
    
global $$foo->bar;

    
// Valid in PHP 5 and 7.
    
global ${$foo->bar};
}
?>

關(guān)于list()處理方式的變更

list() 不再以反向的順序來(lái)進(jìn)行賦值

list() 現在會(huì )按照變量定義的順序來(lái)給他們進(jìn)行賦值,而非反過(guò)來(lái)的順序。 通常來(lái)說(shuō),這只會(huì )影響list() 與數組的[]操作符一起使用的案例,如下所示:

<?php
list($a[], $a[], $a[]) = [123];
var_dump($a);
?>

以上例程在 PHP 5 中的輸出:

array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(1)
}

以上例程在 PHP 7 中的輸出:

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}

總之,我們推薦不要依賴(lài)list()的賦值順序,因為這是一個(gè)在未來(lái)也許會(huì )變更的實(shí)現細節。

空的list()賦值支持已經(jīng)被移除

list() 結構現在不再能是空的。如下的例子不再被允許:

<?php
list() = $a;
list(,,) = 
$a;
list(
$x, list(), $y) = $a;
?>
list()不再能解開(kāi)string

list() 不再能解開(kāi)字符串(string)變量。 你可以使用str_split()來(lái)代替它。

Array ordering when elements are automatically created during by reference assignments has changed

The order of the elements in an array has changed when those elements have been automatically created by referencing them in a by reference assignment. For example:

<?php
$array 
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

以上例程在 PHP 5 中的輸出:

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

以上例程在 PHP 7 中的輸出:

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

函數參數附近的括號不再影響行為

在 PHP 5中,在以引用方式傳遞函數參數時(shí),使用冗余的括號對可以隱匿嚴格標準 的警告?,F在,這個(gè)警告總會(huì )觸發(fā)。

<?php
function getArray() {
    return [
123];
}

function 
squareArray(array &$a) {
    foreach (
$a as &$v) {
        
$v **= 2;
    }
}

// Generates a warning in PHP 7.
squareArray((getArray()));
?>

以上例程會(huì )輸出:

Notice: Only variables should be passed by reference in /tmp/test.php on line 13

foreach的變化

foreach發(fā)生了細微的變化,控制結構, 主要圍繞陣列的內部數組指針和迭代處理的修改。

foreach不再改變內部數組指針

在PHP7之前,當數組通過(guò) foreach 迭代時(shí),數組指針會(huì )移動(dòng)?,F在開(kāi)始,不再如此,見(jiàn)下面代碼

<?php
$array 
= [012];
foreach (
$array as &$val) {
    
var_dump(current($array));
}
?>

以上例程在 PHP 5 中的輸出:

int(1)
int(2)
bool(false)

以上例程在 PHP 7 中的輸出:

int(0)
int(0)
int(0)

foreach 通過(guò)值遍歷時(shí),操作的值為數組的副本

當默認使用通過(guò)值遍歷數組時(shí),foreach 實(shí)際操作的是數組的迭代副本,而非數組本身。這就意味著(zhù),foreach 中的操作不會(huì )修改原數組的值。

foreach通過(guò)引用遍歷時(shí),有更好的迭代特性

當使用引用遍歷數組時(shí),現在 foreach 在迭代中能更好的跟蹤變化。例如,在迭代中添加一個(gè)迭代值到數組中,參考下面的代碼:

<?php
$array 
= [0];
foreach (
$array as &$val) {
    
var_dump($val);
    
$array[1] = 1;
}
?>

以上例程在 PHP 5 中的輸出:

int(0)

以上例程在 PHP 7 中的輸出:

int(0)
int(1)

Traversable 對象的遍歷

迭代一個(gè)非Traversable對象將會(huì )與迭代一個(gè)引用數組的行為相同。 這將導致在對象添加或刪除屬性時(shí),foreach通過(guò)引用遍歷時(shí),有更好的迭代特性也能被應用

int 處理更改

無(wú)效的八進(jìn)制字符(Invalid octal literals)

在之前,一個(gè)八進(jìn)制字符如果含有無(wú)效數字,該無(wú)效數字將被靜默刪節(0128 將被解析為 012). 現在這樣的八進(jìn)制字符將產(chǎn)生解析錯誤。

負位移運算(Negative bitshifts)

以負數形式進(jìn)行的位移運算將會(huì )拋出一個(gè) ArithmeticError

<?php
var_dump
(>> -1);
?>

以上例程在 PHP 5 中的輸出:

int(0)

以上例程在 PHP 7 中的輸出:

Fatal error: Uncaught ArithmeticError: Bit shift by negative number in /tmp/test.php:2
Stack trace:
#0 {main}
  thrown in /tmp/test.php on line 2

超范圍后產(chǎn)生位移

超出 int 位寬的位移操作(無(wú)論哪個(gè)方向)將始終得到 0 作為結果。在從前,這一操作是結構依賴(lài)的。

除以零的變化

之前的版本中,當 0 被做為除數時(shí),無(wú)論是除數 (/) 或取模 (%) 操作,都會(huì )拋出一個(gè) E_WARNING 錯誤并返回 false?,F在,除法運算符 (/) 會(huì )返回一個(gè)由 IEEE 754 指定的浮點(diǎn)數:+INF, -INF 或 NAN。取模操作符 (%) 則會(huì )拋出一個(gè) DivisionByZeroError 異常,并且不再產(chǎn)生 E_WARNING 錯誤。

<?php
var_dump
(3/0);
var_dump(0/0);
var_dump(0%0);
?>

以上例程在 PHP 5 中的輸出:

Warning: Division by zero in %s on line %d
bool(false)

Warning: Division by zero in %s on line %d
bool(false)

Warning: Division by zero in %s on line %d
bool(false)

以上例程在 PHP 7 中的輸出:

Warning: Division by zero in %s on line %d
float(INF)

Warning: Division by zero in %s on line %d
float(NAN)

PHP Fatal error:  Uncaught DivisionByZeroError: Modulo by zero in %s line %d

string處理上的調整

十六進(jìn)制字符串不再被認為是數字

含十六進(jìn)制字符串不再被認為是數字。例如:

<?php
var_dump
("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" "0x1");
var_dump(substr("foo""0x1"));
?>

以上例程在 PHP 5 中的輸出:

bool(true)
bool(true)
int(15)
string(2) "oo"

以上例程在 PHP 7 中的輸出:

bool(false)
bool(false)
int(0)

Notice: A non well formed numeric value encountered in /tmp/test.php on line 5
string(3) "foo"

filter_var() 函數可以用于檢查一個(gè) string 是否含有十六進(jìn)制數字,并將其轉換為 int

<?php
$str 
"0xffff";
$int filter_var($strFILTER_VALIDATE_INTFILTER_FLAG_ALLOW_HEX);
if (
false === $int) {
    throw new 
Exception("Invalid integer!");
}
var_dump($int); // int(65535)
?>

\u{ 可能引起錯誤

由于新的 Unicode codepoint 轉譯語(yǔ)法語(yǔ)法, 緊連著(zhù)無(wú)效序列并包含\u{ 的字串可能引起致命錯誤。 為了避免這一報錯,應該避免反斜杠開(kāi)頭。

被移除的函數(Removed functions)

call_user_method() and call_user_method_array()

這兩個(gè)函數從PHP 4.1.0 開(kāi)始被廢棄,應該使用 call_user_func()call_user_func_array()。 你也可以考慮使用 變量函數 或者 ... 操作符。

所有的 ereg* 函數

所有 ereg 系列函數被刪掉了。 PCRE 作為推薦的替代品。

mcrypt 別名

已廢棄的 mcrypt_generic_end() 函數已被移除,請使用mcrypt_generic_deinit()代替。

此外,已廢棄的 mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb()mcrypt_ofb() 函數已被移除,請配合恰當的MCRYPT_MODE_* 常量來(lái)使用 mcrypt_decrypt()進(jìn)行代替。

所有 ext/mysql 函數

所有 ext/mysql 函數已被刪掉了。 如何選擇不同的 MySQL API,詳情請見(jiàn) 選擇 MySQL API。

所有 ext/mssql 函數

所有 ext/mssql 函數已被移除。

intl 別名

已廢棄的 datefmt_set_timezone_id()IntlDateFormatter::setTimeZoneID() 函數已被移除,請使用 datefmt_set_timezone()IntlDateFormatter::setTimeZone()代替。

set_magic_quotes_runtime()

移除了 set_magic_quotes_runtime() 和它的別名 magic_quotes_runtime()。 它們在 PHP 5.3.0 中已經(jīng)被廢棄, 并由于 PHP 5.4.0 移除魔術(shù)引號(Magic Quotes)而沒(méi)有用處。

set_socket_blocking()

已廢棄的 set_socket_blocking() 函數已被移除,請使用stream_set_blocking()代替。

dl() in PHP-FPM

dl()在 PHP-FPM 不再可用,在 CLI 和 embed SAPIs 中仍可用。

GD Type1 functions

Support for PostScript Type1 fonts has been removed from the GD extension, resulting in the removal of the following functions:

  • imagepsbbox()
  • imagepsencodefont()
  • imagepsextendfont()
  • imagepsfreefont()
  • imagepsloadfont()
  • imagepsslantfont()
  • imagepstext()

推薦使用 TrueType 字體和相關(guān)的函數作為替代。

被移除掉的 INI 配置指令

被移除的功能

以下 INI 配置指令已經(jīng)被移除,同時(shí)移除的還有其對應的功能

  • always_populate_raw_post_data
  • asp_tags

xsl.security_prefs

xsl.security_prefs 指令被移除 在預處理的時(shí)候,取而代之的方法 XsltProcessor::setSecurityPrefs() 應該被調用到

其他向后兼容相關(guān)的變更

new 操作符創(chuàng )建的對象不能以引用方式賦值給變量

new 語(yǔ)句創(chuàng )建的對象不能 以引用的方式賦值給變量。

<?php
class {}
$c =& new C;
?>

以上例程在 PHP 5 中的輸出:

Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3

以上例程在 PHP 7 中的輸出:

Parse error: syntax error, unexpected 'new' (T_NEW) in /tmp/test.php on line 3

無(wú)效的類(lèi)、接口以及 trait 命名

不能以下列名字來(lái)命名類(lèi)、接口以及 trait:

  • bool
  • int
  • float
  • string
  • null
  • true
  • false

此外,也不要使用下列的名字來(lái)命名類(lèi)、接口以及 trait。雖然在 PHP 7.0 中, 這并不會(huì )引發(fā)錯誤, 但是這些名字是保留給將來(lái)使用的。

  • resource
  • object
  • mixed
  • numeric

移除了 ASP 和 script PHP 標簽

使用類(lèi)似 ASP 的標簽,以及 script 標簽來(lái)區分 PHP 代碼的方式被移除。 受到影響的標簽有:

被移除的 ASP 和 script 標簽
開(kāi)標簽 閉標簽
<% %>
<%= %>
<script language="php"> </script>

從不匹配的上下文發(fā)起調用

在不匹配的上下文中以靜態(tài)方式調用非靜態(tài)方法, 在 PHP 5.6 中已經(jīng)廢棄, 但是在 PHP 7.0 中, 會(huì )導致被調用方法中未定義 $this 變量,以及此行為已經(jīng)廢棄的警告。

<?php
class {
    public function 
test() { var_dump($this); }
}

// 注意:并沒(méi)有從類(lèi) A 繼承
class {
    public function 
callNonStaticMethodOfA() { A::test(); }
}

(new 
B)->callNonStaticMethodOfA();
?>

以上例程在 PHP 5.6 中的輸出:

Deprecated: Non-static method A::test() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8
object(B)#1 (0) {
}

以上例程在 PHP 7 中的輸出:

Deprecated: Non-static method A::test() should not be called statically in /tmp/test.php on line 8

Notice: Undefined variable: this in /tmp/test.php on line 3
NULL

yield 變更為右聯(lián)接運算符

在使用 yield 關(guān)鍵字的時(shí)候,不再需要括號, 并且它變更為右聯(lián)接操作符,其運算符優(yōu)先級介于 print=> 之間。 這可能導致現有代碼的行為發(fā)生改變:

<?php
echo yield -1;
// 在之前版本中會(huì )被解釋為:
echo (yield) - 1;
// 現在,它將被解釋為:
echo yield (-1);

yield 
$foo or die;
// 在之前版本中會(huì )被解釋為:
yield ($foo or die);
// 現在,它將被解釋為:
(yield $foo) or die;
?>

可以通過(guò)使用括號來(lái)消除歧義。

函數定義不可以包含多個(gè)同名參數

在函數定義中,不可以包含兩個(gè)或多個(gè)同名的參數。 例如,下面代碼中的函數定義會(huì )觸發(fā) E_COMPILE_ERROR 錯誤:

<?php
function foo($a$b$unused$unused) {
    
//
}
?>

Switch 語(yǔ)句不可以包含多個(gè) default 塊

在 switch 語(yǔ)句中,兩個(gè)或者多個(gè) default 塊的代碼已經(jīng)不再被支持。 例如,下面代碼中的 switch 語(yǔ)句會(huì )觸發(fā) E_COMPILE_ERROR 錯誤:

<?php
switch (1) {
    default:
    break;
    default:
    break;
}
?>

在函數中檢視參數值會(huì )返回 當前 的值

當在函數代碼中使用 func_get_arg()func_get_args() 函數來(lái)檢視參數值, 或者使用 debug_backtrace() 函數查看回溯跟蹤, 以及在異?;厮葜兴鶊蟾娴膮抵凳侵竻诞斍暗闹担ㄓ锌赡苁且呀?jīng)被函數內的代碼改變過(guò)的值), 而不再是參數被傳入函數時(shí)候的原始值了。

<?php
function foo($x) {
    
$x++;
    
var_dump(func_get_arg(0));
}
foo(1);?>

以上例程在 PHP 5 中的輸出:

1

以上例程在 PHP 7 中的輸出:

2

$HTTP_RAW_POST_DATA 被移除

不再提供 $HTTP_RAW_POST_DATA 變量。 請使用 php://input 作為替代。

INI 文件中 # 注釋格式被移除

在 INI 文件中,不再支持以 # 開(kāi)始的注釋行, 請使用 ;(分號)來(lái)表示注釋。 此變更適用于 php.ini 以及用 parse_ini_file()parse_ini_string() 函數來(lái)處理的文件。

JSON 擴展已經(jīng)被 JSOND 取代

JSON 擴展已經(jīng)被 JSOND 擴展取代。 對于數值的處理,有以下兩點(diǎn)需要注意的: 第一,數值不能以點(diǎn)號(.)結束 (例如,數值 34. 必須寫(xiě)作 34.034)。 第二,如果使用科學(xué)計數法表示數值,e 前面必須不是點(diǎn)號(.) (例如,3.e3 必須寫(xiě)作 3.0e33e3)。 另外,空字符串不再被視作有效的 JSON 字符串。

在數值溢出的時(shí)候,內部函數將會(huì )失敗

將浮點(diǎn)數轉換為整數的時(shí)候,如果浮點(diǎn)數值太大,導致無(wú)法以整數表達的情況下, 在之前的版本中,內部函數會(huì )直接將整數截斷,并不會(huì )引發(fā)錯誤。 在 PHP 7.0 中,如果發(fā)生這種情況,會(huì )引發(fā) E_WARNING 錯誤,并且返回 null。

自定義會(huì )話(huà)處理器的返回值修復

在自定義會(huì )話(huà)處理器中,如果函數的返回值不是 false,也不是 -1, 會(huì )引發(fā)致命錯誤?,F在,如果這些函數的返回值不是布爾值,也不是 -1 或者 0,函數調用結果將被視為失敗,并且引發(fā) E_WARNING 錯誤。

相等的元素在排序時(shí)的順序問(wèn)題

由于內部排序算法進(jìn)行了提升, 可能會(huì )導致對比時(shí)被視為相等的多個(gè)元素之間的順序不穩定。

注意:

在對比時(shí)被視為相等的多個(gè)元素之間的排序順序是不可信賴(lài)的,即使是相等的兩個(gè)元素, 他們的位置也可能被排序算法所改變。

錯誤的使用 break 和 switch 語(yǔ)句

在循環(huán)或者 switch 語(yǔ)句之外使用 breakcontinue 被視為編譯型錯誤(之前視為運行時(shí)錯誤),會(huì )引發(fā) E_COMPILE_ERROR 錯誤。

Mhash 不再是一個(gè)單獨的擴展了

Mhash 擴展已經(jīng)被完全整合進(jìn) Hash 擴展了。 因此,不要再使用 extension_loaded() 函數來(lái)檢測是否支持 MHash 擴展了, 建議使用 function_exists() 函數來(lái)進(jìn)行檢測。 另外,函數 get_loaded_extensions() 以及相關(guān)的特性中,也不再報告 和 MHash 擴展相關(guān)的信息了。

declare(ticks)

declare(ticks) 指示符不再泄漏到不同的編譯單元中。

男女疯狂一边摸一边做羞羞视频|啊好深好硬快点用力别停动态图|亚洲一区无码中文字幕|特级无码毛片免费视频播放▽|久久狠狠躁免费观看|国内精品久久久久久网站