2020 年的 PHP 回顧與展望

NiZerin發表於2020-04-04

對於一般的 Web 開發人員和程式設計師來說,PHP 的聲譽並不是很好,這已經是眾所周知。
儘管 PHP 仍然是構建 Web 應用程式最常用的語言之一,但多年來 PHP 已經設法給自己贏得了程式碼庫混亂、開發人員缺乏經驗、程式碼不安全、核心庫不一致等等的名聲。

雖然許多反對 PHP 的論點今天仍然有效,但也有好的一面:您可以用 PHP 編寫乾淨、可維護、快速和可靠的應用程式。

在這篇文章中,我想讓你看到 PHP 開發技術有利的一面。
我想向您展示的是,儘管 PHP 有很多缺點,但它仍然是一門值得學習的語言。
我想讓您知道,PHP5 時代即將結束。
如果你願意的話,你可以寫出現代的、乾淨的 PHP 程式碼,並且把 10 年前的很多爛攤子拋在腦後。

那麼讓我們來看看在過去的幾年裡,這種語言是如何變化的,甚至是如何成熟的。
我想請您把任何偏見放在一邊,只花幾分鐘的時間,現代的 PHP 技術可能會讓你感到驚訝甚至沉迷。

歷史包袱

在深入討論細節之前,讓我們回顧一下 PHP 這門語言目前是如何一步一步發展的。
現在的 PHP 版本是 7.4,PHP8.0 將是下一個版本,也就是 2020 年底。

自從 5.* 時代末以來,核心團隊試圖保持一致的年度釋出週期,並且在過去的四年中已經成功做到了這一點。

一般來說,每個新版本都會得到為期兩年的積極支援,並且會再獲得一年的“僅限安全修復”。
其目標是激勵開發人員儘可能保持最新狀態:例如,每年的小升級比在 5.4 到 7.0 之間的跳躍要容易得多。

最後,PHP5.6 是最新的 5.* 版本,下一個版本是 7.0。
如果你想知道 PHP6 發生了什麼,你可以點選檢視這篇文章

PHP 現在的底層開發是由一群社群志願者完成的,他們中的一些人是由僱主付錢讓他們全職從事核心工作的。
大多數關於這種語言是如何發展的討論都是在郵件列表上進行的。

現在這些歷史問題你都有所瞭解了,讓我們揭祕一些關於現代 PHP 的常見誤解。

PHP的型別系統

PHP 一開始是一種非常弱的、動態型別的語言,這在當時有它的好處。
但是,自從人們開始在較大的專案中使用 PHP 以來,它的型別系統的缺點就變得明顯起來,並且出現了對更強的型別支援的需求。

今天,PHP 是一種相當獨特的語言:它仍然允許您編寫完全動態的弱型別程式碼,但也有一個更強大的、可選擇的型別系統。
結合靜態分析工具,如 Psalm、Phan 和 PHPStan,您可以編寫安全、強型別和靜態分析的程式碼。

例如,看看這段 PHP 程式碼,它完全使用了它的現代型別系統:

<?php

declare(strict_types=1);

final class Foo
{
    public int $intProperty = 2;

    public ?string $nullableString = null;

    private Bar $bar;

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

    public function withInt(int $value): self
    {
        $clone = clone $this;

        $clone->intProperty = $value;

        return $clone;
    }

    public function unionTypes(int|float $input): void
    {
        // Union types will be added in PHP 8
    }
}

說實話,PHP 的型別系統中仍然缺少一個重要特性:泛型。
他們有希望被加入,但目前還沒有什麼具體的東西。
如果是型別化陣列,您將需要依賴文件塊來獲得適當的 IDE 支援:

/** @var int[] */
public array $arrayOfInts = [];

雖然型別化陣列是泛型的常見用例,可以使用 Docblock 解決,但我們錯過了更多功能,因為它們不是…語言。
現在還不行。

PHP的語法

在語法方面,7.* 時代在使 PHP 成為更成熟的語言方面做了很多好事。
為了說明這一點,我在 PHP 中列出了一個非詳盡的新功能列表。

陣列解構:

[$a, $b] = $array;

空合併運算子:

$value = $object->property ?? 'fallback if null';

$value = $array['foo'] ?? "fallback if key doesn't exists"; 

空合併賦值運算子:

public function get(string $input): string 
{
    return $this->cache[$input] ??= $this->sanitize($input);
}

陣列擴充套件:

$a = [/* … */];
$b = [/* … */];

$mergedArray = [...$a, ...$b];

可變的函式:

public function get(Foo ...$foos): void
{
    foreach($foos as $foo) {
        // …
    }
}

引數解包:

$this->get(...$arrayOfFoo);

型別化屬性:

public int $intProperty;

箭頭函式,也稱為短閉包:

$ids = array_map(fn(Post $post): int => $post->id, $posts);

生成器:

function make(array $input): Generator
{
    foreach ($input as $item) {
        yield $this->doSomethingWith($item);
    }
}

還有更多。
我希望從這份列表中可以清楚地看到,PHP 今天仍在不斷髮展,您可以肯定還會有更多的好東西問世。

PHP的效能

在過去的 5.* 時代裡,php 的效能是不可描述的。
充其量也就是一般。
但是,在 7.0 版本中,PHP 核心的很大一部分被從頭開始重寫,導致效能提高了兩三倍。
此外,每個 7.* 版本都對效能產生了積極影響。

不過,光靠語言是不夠的。
讓我們來看看基準測試。
幸運的是,其他人已經花了大量時間對PHP效能進行基準測試。
我發現 Kinsta 有一個很好的測評文章。

與效能相關的最新特性稱為預載入,它基本上允許您將編譯後的 PHP 程式碼部分儲存在記憶體中。
你可以看看這裡的一些基準。

當 PHP8 問世時,我們還將擁有一個 JIT 編譯器,承諾進行有趣的效能改進,並允許 PHP 進入 web 開發以外的新領域。

框架和生態系統

接下來介紹社群使用 PHP 所做的工作。
讓我們明確一下:恰恰相反,PHP 不再僅僅是 WordPress。

一般來說,有兩個主要的Web應用程式框架,以及一些較小的框架:symfony 和 Laravel。
當然也有 Lamina,Yii,Cake,Code igniter 等等–但是如果你想知道現代 PHP 開發是什麼樣子,前兩個中的一個是不錯的。

這兩個框架都有一個龐大的軟體包和產品生態系統。
從管理皮膚和 CRM 到獨立的軟體包,CI 到分析器,無數的服務,如 WebSockets 伺服器,佇列管理器,支付整合;老實說,有太多的東西要列出。

這些框架是為實際開發而設計的;如果您需要純粹的內容管理,WordPress、CraftCMS 和 Static 等平臺正在不斷改進。

衡量 PHP 生態系統當前狀態的一種方法是檢視 PHP 的主包儲存庫 Packagist。
它經歷了指數級的增長。
每天的下載量為±2500萬次,可以公平地說 PHP 生態系統不再像過去那樣處於劣勢了。

請看此圖,其中列出了一段時間內軟體包和版本的數量。
它也可以在 Packagist^2 ^網站上找到。

除了應用程式框架和 CMS 之外,我們還看到非同步框架在過去幾年中的興起。
這些是用 PHP 或其他語言編寫的框架和伺服器,允許使用者執行真正非同步的 PHP 程式碼。
一些主要的玩家是 Swoole,Amp 和 ReactPHP。

自從我們冒險進入非同步世界以來,像 websockets 和具有大量 IO 的應用程式這樣的東西實際上已經與 PHP 世界相關了。

也有關於將 libuv 新增到核心的內部郵件列表的討論。
對於那些沒有意識到 libuv 的人來說:它與 Node.js 用來允許其所有非同步性的庫相同。
誰知道呢?
PHP8 可能是將其新增到核心的版本!

寫在最後

我希望我能夠向您展示 PHP 在過去幾年中有了巨大的發展,您完全能夠用它編寫乾淨和可維護的程式碼。

如果您對目前流行的 PHP 程式碼感興趣,可以檢視我自己的一個專案的原始碼,以及我們親自維護的許多開放原始碼包。

因此,雖然這門語言肯定有它的缺點和 20 年的歷史遺產,但我可以自信地說,我喜歡使用它。

根據我的經驗,我能夠建立可靠的、可維護的、高質量的軟體。
我為之工作的客戶對最終結果很滿意,我也是。雖然仍然有可能用 PHP 做很多亂七八糟的事情,但我想說,如果使用得當,它仍是 Web 開發的一個很好的選擇。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

By: Laravel-China 寧澤林
MyBlog: nizer.in

相關文章