Laravel 10 新功能 PHP 8.1 Pennant Process 多執行緒
Laravel PHP

Laravel 10 的新功能:最低要求 PHP 8.1,Laravel Pennant 實現 feature flag,Process facade 執行外部程式

商業,創業,業務,職涯,美食,葡萄酒,閱讀,網路科技。

從 Larry 創業以及商業的經驗,希望以白話的口吻,介紹給大家這個商業的世界。

FB粉專會頻繁地更新 Larry 對於商業、社會、人生的觀察與心得,歡迎大家追蹤互動~

https://laravel-news.com/laravel-10
前幾天 (2023年2月中) Laravel 10 發佈了。

我之前的文章 Laravel 9 的新功能 有提到,從 Laravel 9 開始,major version 每一年更新一次,目前是訂在每年的二月更新 major version。

以下是 Laravel 10 的一些主要更新和新功能:

PHP 8.1 是 Laravel 10 最低的 PHP 版本要求

PHP 8.0 不行喔,檢查你的主機環境是不是 PHP 8.1 以上,才有辦法跑 Laravel 10。

新的 Laravel Pennant 套件

Laravel 10 發佈了新的 Laravel Pennant 套件。Laravel Pennant 的邏輯是,先定義一個使用者的條件,也許他是 beta tester,也許他是公司中某些指定的用戶。

這就是軟體工程的 Feature Flag。在「正式站」中上線多個程式碼分支,只有預先定義的部分用戶,可以使用新功能以及做最終測試。

參考官方文件 https://laravel.com/docs/10.x/pennant

來自上方文件的 sample code,你可以在 AppServiceProvider 定義使用者的資格

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Feature::define('new-api', fn(User $user) => match (true) {
            $user->isInternalTeamMember() => true,
            $user->isHighTrafficCustomer() => false,
            default => Lottery::odds(1 / 100),
        });
    }
}

‘new-api’ 字串是你定義的 feature name。larry 很喜歡這一段 sample code,是因為它同時用了 PHP 7.4 的 arrow function,和 PHP 8 的 match expression。

字面上看,如果用戶是內部 team member,或「不是」高流量的客戶,都給這個用戶使用 ‘new-api’。如果用戶「不是」內部 team member,又使用了高流量,就會 return default: 抽籤決定這個用戶可不可以使用 ‘new-api’。

這段 sample code 寫得很漂亮,很有意思。

上面 ‘new-api’ 是字串,也可以改為使用 class based 寫法

namespace App\Features;
  
class NewApi
{
    /**
     * Resolve the feature's initial value.
     */
    public function resolve(User $user): mixed
    {
        return match (true) {
            $user->isInternalTeamMember() => true,
            $user->isHighTrafficCustomer() => false,
            default => Lottery::odds(1 / 100),
        };
    }
}

你在 controller 裡就可以用 Feature::activeFeature::when 去確認使用者資格,並做相對應的動作

public function index(Request $request): Response
{
        return Feature::active(NewApi::class)
                ? $this->resolveNewApiResponse($request)
                : $this->resolveLegacyApiResponse($request);
}

public function index(Request $request): Response
{
        return Feature::when(NewApi::class,
            fn() => $this->resolveNewApiResponse($request),
            fn() => $this->resolveLegacyApiResponse($request),
        );
}

以上大概就是 Laravel Pennant 的邏輯。不用這個套件其實本來就可以寫這樣的效果,只是 Laravel Pennant 把這個需求的寫法架構化了。

新的 Process facade

https://laravel.com/docs/10.x/processes
新的 Process facade 讓開發者可以輕易的執行 Laravel 專案外,也就是作業系統層級的指令。例如官方文件的 sample code

use Illuminate\Support\Facades\Process;
 
$result = Process::run('ls -la');
// run function 是同步執行,也就是有可能會 hang 住 
return $result->output();

也可以指定要下命令的資料夾路徑

$result = Process::path(__DIR__)->run('ls -la');

上面 run function 是同步執行 (sync) 外部指令,也就是執行的當下有可能會 hang 住。而 start function 是非同步執行 (async)

$process = Process::timeout(120)->start('bash import.sh');
// 執行 120 秒沒完成的話,throw timeout exception 

while ($process->running()) {
    // ...
}
 
$result = $process->wait();
// 這一行會等 process 執行完 (有可能會 hang 住)
// 拿到 result

如果讀者是資深的軟體開發者,尤其是當年是 C++ 出身的,應該有感,這就是 multi-thread (多執行緒) 的概念啊。

Process facade 也包含了類似 thread pool 的功能。

use Illuminate\Process\Pool;
use Illuminate\Support\Facades\Process;
 
$pool = Process::pool(function (Pool $pool) {
    $pool->path(__DIR__)->command('bash import-1.sh');
    $pool->path(__DIR__)->command('bash import-2.sh');
    $pool->path(__DIR__)->command('bash import-3.sh');
})->start(function (string $type, string $output, int $key) {
    // ...
});

// 執行 import-1.sh, import-2.sh, import-3.sh
 
while ($pool->running()->isNotEmpty()) {
    // ...
}
 
$results = $pool->wait();

講到 multi-thread、thread pool,或是 process pool,真是讓我想起一些回憶,也許這就是寫部落格的好處之一吧,哈哈。

延伸閱讀,我2013年1月的文章:Multi-thread 多執行緒程式設計

Laravel framework 整個更新標示 function parameter type & return type

將現代 PHP feature 帶入 Laravel framework 中,明確的標示 function parameter type & return type。

Invokable validation rule 指令調整

// Laravel 9 產生 Rule Object with __invoke function
artisan make:rule Uppercase --invokable

// Laravel 10 做一樣的事,不用 --invokable flag
artisan make:rule Uppercase

新的 test 指令選項,顯示測試執行秒數

php artisan test --profile

上面指令會執行測試,並將每個測試的執行時間,由慢到快排序出來。開發者可以輕易找到,跑得過慢的測試。

新的 Str::password helper function

Str::password() 預設會產生 32 位長度的英文、數字、符號、空白,混合字串。輸入參數也可以指定字串長度。

結論

這次 Laravel 10 主要是 Laravel Pennant 和 Process facade 的導入。Laravel Pennant 功能上 larry 覺得還好,相同功能本來就可以用其他方式寫。倒是官方文件 sample code 同時用了 PHP 7.4 的 arrow function,和 PHP 8 的 match expression,這個寫法是很漂亮的。

Process facade 其實就是 multi-thread 程式設計。sync、async,甚至 thread pool 都實作出來了。如果開發者需要執行 Laravel 專案外,也就是作業系統層級的指令,應該是更方便了。

延伸閱讀:Multi-thread 多執行緒程式設計

商業,創業,業務,職涯,美食,葡萄酒,閱讀,網路科技。

從 Larry 創業以及商業的經驗,希望以白話的口吻,介紹給大家這個商業的世界。

FB粉專會頻繁地更新 Larry 對於商業、社會、人生的觀察與心得,歡迎大家追蹤互動~