中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP8.2有哪些新特性

發布時間:2022-07-05 09:17:28 來源:億速云 閱讀:560 作者:iii 欄目:編程語言

這篇“PHP8.2有哪些新特性”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“PHP8.2有哪些新特性”文章吧。

null和false將作為獨立的類型

PHP并不會陷入到完美的類型安全方向中,但是從技術的角度考慮,將null和false作為獨立的數據類型是值得的。一般情況下,PHP的很多常見的函數,會通過返回false表示出錯了。比如在file_get_content中:

file_get_contents(/* … */): string|false

在以前,false可以在聯合類型中使用,但是不能獨立使用,在PHP8.2中可以單獨使用:

function alwaysFalse(): false
{
    return false;
}

當然,對于這個做法,一些開發者都持謹慎態度。他并不支持true作為獨立類型。這些開發者們認為,false只是一個值,類型應該代表類別而不是一個值。當然在類型系統中,有一個概念是單元類型,它是只允許一個值的類型。但是這真的有用嗎?

不過另一個RFC也正在討論將true作為一種類型添加到PHP中。

一個獨立的null卻很有意義,這樣可以簡單地實現空對象模式:

class Post
{
    public function getAuthor(): ?string { /* … */ }
}

class NullPost extends Post
{
    public function getAuthor(): null { /* … */ }
}

這對NullPost::getAuthor()能夠說它只會返回null,不必像以前那樣必須將null和string一起聯合聲明。

棄用動態屬性

對于語言規范來說,這是更好的設計,但是也會限制很多用法。動態屬性在PHP8.2中被棄用,并且會在PHP中拋出錯誤異常。

什么是動態屬性?就是你沒有在類中聲明這些屬性,但是仍然可以設置和獲取:

class Post
{
    public string $title;
}

// …

$post->name = 'Name';  // 在PHP8.2中不能這樣使用,因為并沒有在類中聲明

不過放心,__set和__get等魔術方法將仍然按預期中工作:

class Post
{
    private array $properties = [];

    public function __set(string $name, mixed $value): void
    {
        $this->properties[$name] = $value;
    }
}

// …

$post->name = 'Name';

標準對象也是如此:stdClass將繼續支持動態屬性。

PHP曾經是一種動態程度很強的動態語言,但是現在已經有很多人愿意接受更加嚴格的編程方式了。盡可能的嚴格,盡可能的依賴靜態分析是一件好事,這能讓開發者們寫出更好的代碼。

不過可能一部分很看重動態屬性的開發人員對這種變化會很不滿意,如果你不想在使用PHP8.2時看到這些警告,可以這樣做:

可以使用#[AllowDynamicProperties]

#[AllowDynamicProperties]
class Post
{
    public string $title;
}

// …

$post->name = 'Name'; // 一切正常

另一種方法是修改報警級別,但不建議這樣做。等你打算升級到PHP9.0時會遇到麻煩。

error_reporting(E_ALL ^ E_DEPRECATED);

追蹤調用時參數脫敏

什么叫參數脫敏?在我們開發時,遇到錯誤,都會使用Trace調試,但是目前的堆棧記錄下一些敏感數據,比如環境變量、密碼、用戶。

在PHP8.2中允許對參數進行一些編訂( Redact ,姑且叫做編訂,有一些修飾的意思,但直接稱為修飾并不合適),比如將一些參數設置脫敏,這樣這些參數的調用值不會在堆棧信息中列出:

function test(
    $foo,
    #[\SensitiveParameter] $bar,
    $baz
) {
    throw new Exception('Error');
}

test('foo', 'bar', 'baz');

如果報錯的話,會發現,第二個參數bar并沒有記錄實際的值。這樣能起到脫敏的作用,如果傳的是密碼的話,就不會別記錄下來。

Fatal error: Uncaught Exception: Error in test.php:8
Stack trace:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {main}
  thrown in test.php on line 8

棄用了部分對象的調用方式

一些以前的調用對象方式杯棄用了。這里面一些是需要通過call_user_func($callable)來調用的,而不是能夠$callable()直接調用的。

"self::method"
"parent::method"
"static::method"
["self", "method"]
["parent", "method"]
["static", "method"]
["Foo", "Bar::method"]
[new Foo, "Bar::method"]

為什么要這樣做呢?Nikita在RFC討論中很好的做出了解釋:

這些廢棄的調用都是有關上下文的, “self::method”所指的方法取決于從哪個類執行調用或可調用性檢查。實際上,當以[new Foo, "parent::method"]的形式使用時,這通常也適用于最后兩種情況。

減少可調用對象的上下文相關性是本RFC的次要目標。在這個RFC之后,唯一剩下的范圍依賴是方法可見性:“Foo::bar”可能在一個范圍內可見,但在另一個范圍內不可見。如果將來可調用對象僅限于公共方法,那么可調用類型將變得明確定義并且可以用作屬性類型。但是,對可見性處理的更改不建議作為本RFC的一部分。

提升對未定義變量的檢測機制和級別

未定義的變量是那些在被讀取之前還沒有被初始化的變量。訪問未定義的變量當前會發出E_WARNING“警告:未定義的變量$varname”,并將變量視為null,但不會中斷執行,從而允許代碼執行繼續有增無減,但可能處于意外狀態。

目前可以通過一些配置,讓PHP執行時對未定義變量產生錯誤級異常,但這需要單獨配置。PHP應當默認提供更安全的檢驗。

一般什么情況下會出現未定義變量的情況呢?

用法1

變量在某個分支中聲明,比如在if中設置一個值。

if  ( $user -> admin )  {
   $restricted  =  false ;
}

if  ( $restricted )  {
   die ( '你沒有進入這里的權限' ) ;
}

用法2

變量拼寫錯誤:

$name = 'Joe';
echo 'Welcome, ' . $naame;

這種用法在1中也可能會發生:

if ($user->admin) {
   $restricted = false;
} else {
   $restrictedd = true;
}

if ($restricted) {
   die('You do not have permission to be here');
}

用法3

在循環中定義,但這個循環可能并沒有執行:

while ($item = $itr->next()) {

   $counter++; // 定義變量
}

  // 這里調用了變量,但是很有可能并沒有定義這個變量
echo 'You scanned ' . $counter . ' items';

解決方法

在這些分支之前提前定義好一個默認值。

對于第1種用法:

$restricted = true;
if ($user->admin) {
   $restricted = false;
}

if ($restricted) {
   die('You do not have permission to be here');
}

對于第3種用法:

$counter = 0;
while ($item = $itr->next()) {
   $counter++;
}

echo 'You scanned ' . $counter . ' items';

這樣做的好處是消除了整個訪問和使用這些未定義變量的后果,以及回退到引擎默認狀態的用戶態錯誤。這樣我們提供了另一層保護,防止PHP程序發生了這種意外后繼續運行。

這種更改也會讓PHP引擎和JIT等方面不會那么復雜。

這個版本主要是針對PHP9.0的,在PHP8.2的還是警告,在以后會將這種行為提升到錯誤級別。

增加只讀類

通過給類添加只讀修飾符來聲明只讀類。

readonly class Test {
    public string $prop;
}

這樣做會隱式地將類的所有實例屬性標記為只讀。此外,它將阻止創建動態屬性。

readonly class Foo
{
    public int $bar;

    public function __construct() {
        $this->bar = 1;
    }
}

$foo = new Foo();
$foo->bar = 2;
// 拋出錯誤,不能修改只讀屬性 Foo::$bar

$foo->baz = 1;
// 拋出錯誤:不能動態創建屬性 Foo::$baz

可以通過增加#[AllowDynamicProperties]屬性,可以不觸發錯誤的情況下創建動態屬性。

#[AllowDynamicProperties]
readonly class Foo {
}

一些限制:

由于是只讀類,必須對屬性聲明類型:

readonly class Foo
{
    public $bar;
}
// 以上定義會產生錯誤。

不能使用靜態屬性:

readonly class Foo
{
    public static int $bar;
}
// 拋出錯誤: 只讀屬性不能聲明靜態類型

以上就是關于“PHP8.2有哪些新特性”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

鄂托克旗| 阿拉善盟| 德令哈市| 明光市| 南部县| 长葛市| 宁明县| 太和县| 临潭县| 夏津县| 屯门区| 于都县| 北京市| 清远市| 宁河县| 孝感市| 盐山县| 中山市| 潼南县| 志丹县| 黎城县| 绥棱县| 京山县| 顺昌县| 咸丰县| 县级市| 梅州市| 天门市| 镇安县| 大关县| 临武县| 娄底市| 丰镇市| 乌恰县| 大渡口区| 乐安县| 赞皇县| 万源市| 柘荣县| 普兰县| 根河市|