亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

首頁 後端開發(fā) php教程 Laravel 11 中的 PHP 泛型

Laravel 11 中的 PHP 泛型

Oct 23, 2024 am 08:08 AM

PHP Generics in Laravel 11

如果您是Laravel 的Web 應(yīng)用程式建構(gòu)者,並且碰巧使用PHPStan 進(jìn)行靜態(tài)程式碼分析,那麼當(dāng)您升級(jí)到Laravel 11.x.

使用

PHPStan 全新安裝 Laravel 時(shí),第一次執(zhí)行 ./vendor/bin/phpstan 時(shí)會(huì)拋出以下錯(cuò)誤:

 ------ -----------------------------------------------------------------------------------
  Line   app\Models\User.php
 ------ -----------------------------------------------------------------------------------
  13     Class App\Models\User uses generic trait
         Illuminate\Database\Eloquent\Factories\HasFactory but does not specify its types:
         TFactory
 ------ -----------------------------------------------------------------------------------
那麼改變了什麼?在 Laravel 11 中,HasFactory 特徵現(xiàn)在有一個(gè)

PHPDoc 和 @template 標(biāo)籤,這是保留的泛型標(biāo)籤之一。正如您可能已經(jīng)猜到的,框架的許多部分都使用了泛型。

/**
 * @template TFactory of \Illuminate\Database\Eloquent\Factories\Factory
 */
trait HasFactory
{
    ...
}
雖然不建議這樣做,但只需將這些程式碼行新增到您的 phpstan.neon 檔案即可忽略此類錯(cuò)誤:


parameters:
    ignoreErrors:
        -
            identifier: missingType.generics
但是,泛型並不難理解,所以讓我們開始吧!

什麼是泛型?

程式設(shè)計(jì)中的泛型是指允許您編寫可處理多種資料類型的程式碼的功能。您無需為每種資料類型編寫單獨(dú)的程式碼,而是可以編寫一段通用的程式碼,該程式碼可以在保持類型安全的同時(shí)對(duì)各種類型進(jìn)行操作,這與使用混合或物件等通用類型不同。

採用

Laravel 10 中的 IlluminateDatabaseConcernsBuildsQueries::first 方法,它可以傳回 Model 的實(shí)例、通用物件、像 IlluminateDatabaseEloquentBuilder 一樣使用它的類別的實(shí)例或 null。

/**
 * Execute the query and get the first result.
 *
 * @param  array|string  $columns
 * @return \Illuminate\Database\Eloquent\Model|object|static|null
 */
public function first($columns = ['*'])
{
    return $this->take(1)->get($columns)->first();
}
泛型語法

PHP 中不支援泛型作為一等公民,為了擁有它們,我們使用

PHPDocs 標(biāo)籤 @template、@template-covariant、@template-contravariant、@extends、@implements 和@使用。

泛型類型的規(guī)則是使用

型別參數(shù)定義的。 PHPDocs中,我們使用@template標(biāo)籤對(duì)它們進(jìn)行註釋。類型參數(shù)名稱可以是任何名稱,只要不使用現(xiàn)有的類別名稱即可。您也可以使用 of 關(guān)鍵字限制可以使用哪些類型來取代帶有上限的類型參數(shù)。這稱為有界型參數(shù)。

<?php

namespace Illuminate\Database\Eloquent;

/**
 * @template TModel of \Illuminate\Database\Eloquent\Model
 *
 */
class Builder implements BuilderContract
{
}
PHP 泛型的類型

通用函數(shù)

泛型函數(shù)與普通函數(shù)完全相同,但是它具有型別參數(shù)。這允許以更通用的方式使用通用方法。

以 IlluminateSupportValidatedInput::enum 方法為例:

  • 它定義了一個(gè)型別參數(shù) TEnum。

  • $enumClass 參數(shù)是偽型別 class-string,並且綁定到相同型別參數(shù) TEnum。

  • 回傳型別也可以是 TEnum 或 null。


 ------ -----------------------------------------------------------------------------------
  Line   app\Models\User.php
 ------ -----------------------------------------------------------------------------------
  13     Class App\Models\User uses generic trait
         Illuminate\Database\Eloquent\Factories\HasFactory but does not specify its types:
         TFactory
 ------ -----------------------------------------------------------------------------------

如果您隨後呼叫 $request→validated()→enum('status', OrderStatus::class),PHPStan 將知道您正在取得 OrderStatus 物件或 null!

通用類別

泛型類別允許建立可以對(duì)任何資料類型進(jìn)行操作的類,同時(shí)確保類型安全。它們?cè)试S使用特定類型的佔(zhàn)位符來定義類,稍後可以在類實(shí)例化時(shí)替換該佔(zhàn)位符。

Laravel 原始碼中的一個(gè)很好的例子是 IlluminateDatabaseEloquentBuilder 類別:

/**
 * @template TFactory of \Illuminate\Database\Eloquent\Factories\Factory
 */
trait HasFactory
{
    ...
}

類型參數(shù) TModel 被定義並綁定到 IlluminateDatabaseEloquentModel 的任何子類別。相同的型別參數(shù)用作 make 方法的傳回類型。

另一個(gè)例子是,如果我們有一個(gè)訂單模型,它有一個(gè)本地範(fàn)圍來根據(jù)訂單狀態(tài)過濾訂單。範(fàn)圍方法應(yīng)指定 TModel 類型

parameters:
    ignoreErrors:
        -
            identifier: missingType.generics

?? info:命名空間 IlluminateDatabaseEloquentRelations 中的所有 Eloquent 關(guān)係類別(例如 BelongsTo 和 HasOne)現(xiàn)在都是通用的。

通用介面

通用介面並沒有那麼不同。 IlluminateContractsSupportArrayable 是通用介面的範(fàn)例

/**
 * Execute the query and get the first result.
 *
 * @param  array|string  $columns
 * @return \Illuminate\Database\Eloquent\Model|object|static|null
 */
public function first($columns = ['*'])
{
    return $this->take(1)->get($columns)->first();
}

此介面定義了兩個(gè)型別參數(shù):array-key類型的TKey(可以是int或string)和TValue。這兩個(gè)參數(shù)用於定義 toArray 函數(shù)的傳回類型。這是一個(gè)例子:

<?php

namespace Illuminate\Database\Eloquent;

/**
 * @template TModel of \Illuminate\Database\Eloquent\Model
 *
 */
class Builder implements BuilderContract
{
}

使用者類別實(shí)作 Arrayable 接口,並指定 Tkey 類型為 int,TValue 型為 string。

通用特徵

我們?cè)诒疚拈_頭的錯(cuò)誤中遇到了 IlluminateDatabaseEloquentFactoriesHasFactory 特徵。讓我們仔細(xì)看看:

/**
 * @template TEnum
 *
 * @param string $key
 * @param class-string<TEnum> $enumClass
 * @return TEnum|null
 */
public function enum($key, $enumClass)
{
    if ($this->isNotFilled($key) ||
        ! enum_exists($enumClass) ||
        ! method_exists($enumClass, 'tryFrom')) {
        return null;
    }
    return $enumClass::tryFrom($this->input($key));
}

HasFactory 定義了一個(gè)型別參數(shù) TFactory,它綁定到 IlluminateDatabaseEloquentFactoriesFactory 的子類別。那麼要如何修復(fù)這個(gè)錯(cuò)誤呢?

使用 Trait 時(shí)必須指定 TFactory 類型。因此,HasFactory 特徵的 use 語句需要使用 PHPDocs @use:
進(jìn)行註釋

<?php

namespace Illuminate\Database\Eloquent;
/**
 * @template TModel of \Illuminate\Database\Eloquent\Model
 */
class Builder implements BuilderContract
{
    /**
     * @param  array  $attributes
     * @return TModel
     */
    public function make(array $attributes = [])
    {
        return $this->newModelInstance($attributes);
    }
}

保持通用性

擴(kuò)充類別、實(shí)作介面或使用特徵時(shí),可以保持子類別中的通用性。

透過在子類別上方定義相同的類型參數(shù)並將其傳遞給 @extends、@implements 和 @use 標(biāo)籤來實(shí)現(xiàn)保留通用性。

我們將使用 IlluminateDatabaseConcernsBuildsQueries 通用特徵作為範(fàn)例,

它定義了一個(gè)型別參數(shù)TValue:

 ------ -----------------------------------------------------------------------------------
  Line   app\Models\User.php
 ------ -----------------------------------------------------------------------------------
  13     Class App\Models\User uses generic trait
         Illuminate\Database\Eloquent\Factories\HasFactory but does not specify its types:
         TFactory
 ------ -----------------------------------------------------------------------------------

IlluminateDatabaseEloquentBuilder 類別使用此特徵,但透過向其傳遞 TModel 參數(shù)類型來保持其通用性?,F(xiàn)在由客戶端程式碼來指定 TModel 的類型,從而在 BuildsQueries 特徵中指定 TValue。

/**
 * @template TFactory of \Illuminate\Database\Eloquent\Factories\Factory
 */
trait HasFactory
{
    ...
}

最後的想法

總之,雖然 PHP 並不像其他程式語言那樣原生支援泛型,但引入高階類型提示和工具(例如 PHPStan)允許開發(fā)人員在程式碼中實(shí)現(xiàn)類似泛型的功能。透過利用 PHPDocs、參數(shù)化類別和接口,您可以創(chuàng)建更靈活和類型安全的應(yīng)用程序,從而提高程式碼的可重用性和可維護(hù)性。隨著 PHP 的不斷發(fā)展,社群對(duì)類型安全和靜態(tài)分析的日益關(guān)注可能會(huì)帶來更強(qiáng)大的泛型實(shí)現(xiàn)解決方案。接受這些實(shí)踐不僅可以提高您的編碼技能,還有助於開發(fā)經(jīng)得起時(shí)間考驗(yàn)的高品質(zhì)軟體。

以上是Laravel 11 中的 PHP 泛型的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
PHP變量範(fàn)圍解釋了 PHP變量範(fàn)圍解釋了 Jul 17, 2025 am 04:16 AM

PHP變量作用域常見問題及解決方法包括:1.函數(shù)內(nèi)部無法訪問全局變量,需使用global關(guān)鍵字或參數(shù)傳入;2.靜態(tài)變量用static聲明,只初始化一次並在多次調(diào)用間保持值;3.超全局變量如$_GET、$_POST可在任何作用域直接使用,但需注意安全過濾;4.匿名函數(shù)需通過use關(guān)鍵字引入父作用域變量,修改外部變量則需傳遞引用。掌握這些規(guī)則有助於避免錯(cuò)誤並提升代碼穩(wěn)定性。

如何在PHP中牢固地處理文件上傳? 如何在PHP中牢固地處理文件上傳? Jul 08, 2025 am 02:37 AM

要安全處理PHP文件上傳需驗(yàn)證來源與類型、控製文件名與路徑、設(shè)置服務(wù)器限制並二次處理媒體文件。 1.驗(yàn)證上傳來源通過token防止CSRF並通過finfo_file檢測(cè)真實(shí)MIME類型使用白名單控制;2.重命名文件為隨機(jī)字符串並根據(jù)檢測(cè)類型決定擴(kuò)展名存儲(chǔ)至非Web目錄;3.PHP配置限制上傳大小及臨時(shí)目錄Nginx/Apache禁止訪問上傳目錄;4.GD庫重新保存圖片清除潛在惡意數(shù)據(jù)。

在PHP中評(píng)論代碼 在PHP中評(píng)論代碼 Jul 18, 2025 am 04:57 AM

PHP註釋代碼常用方法有三種:1.單行註釋用//或#屏蔽一行代碼,推薦使用//;2.多行註釋用/.../包裹代碼塊,不可嵌套但可跨行;3.組合技巧註釋如用/if(){}/控制邏輯塊,或配合編輯器快捷鍵提升效率,使用時(shí)需注意閉合符號(hào)和避免嵌套。

發(fā)電機(jī)如何在PHP中工作? 發(fā)電機(jī)如何在PHP中工作? Jul 11, 2025 am 03:12 AM

AgeneratorinPHPisamemory-efficientwaytoiterateoverlargedatasetsbyyieldingvaluesoneatatimeinsteadofreturningthemallatonce.1.Generatorsusetheyieldkeywordtoproducevaluesondemand,reducingmemoryusage.2.Theyareusefulforhandlingbigloops,readinglargefiles,or

撰寫PHP評(píng)論的提示 撰寫PHP評(píng)論的提示 Jul 18, 2025 am 04:51 AM

寫好PHP註釋的關(guān)鍵在於明確目的與規(guī)範(fàn),註釋應(yīng)解釋“為什麼”而非“做了什麼”,避免冗餘或過於簡(jiǎn)單。 1.使用統(tǒng)一格式,如docblock(/*/)用於類、方法說明,提升可讀性與工具兼容性;2.強(qiáng)調(diào)邏輯背後的原因,如說明為何需手動(dòng)輸出JS跳轉(zhuǎn);3.在復(fù)雜代碼前添加總覽性說明,分步驟描述流程,幫助理解整體思路;4.合理使用TODO和FIXME標(biāo)記待辦事項(xiàng)與問題,便於後續(xù)追蹤與協(xié)作。好的註釋能降低溝通成本,提升代碼維護(hù)效率。

如何通過php中的索引訪問字符串中的字符 如何通過php中的索引訪問字符串中的字符 Jul 12, 2025 am 03:15 AM

在PHP中獲取字符串特定索引字符可用方括號(hào)或花括號(hào),但推薦方括號(hào);索引從0開始,超出範(fàn)圍訪問返回空值,不可賦值;處理多字節(jié)字符需用mb_substr。例如:$str="hello";echo$str[0];輸出h;而中文等字符需用mb_substr($str,1,1)獲取正確結(jié)果;實(shí)際應(yīng)用中循環(huán)訪問前應(yīng)檢查字符串長度,動(dòng)態(tài)字符串需驗(yàn)證有效性,多語言項(xiàng)目建議統(tǒng)一使用多字節(jié)安全函數(shù)。

快速PHP安裝教程 快速PHP安裝教程 Jul 18, 2025 am 04:52 AM

ToinstallPHPquickly,useXAMPPonWindowsorHomebrewonmacOS.1.OnWindows,downloadandinstallXAMPP,selectcomponents,startApache,andplacefilesinhtdocs.2.Alternatively,manuallyinstallPHPfromphp.netandsetupaserverlikeApache.3.OnmacOS,installHomebrew,thenrun'bre

學(xué)習(xí)PHP:初學(xué)者指南 學(xué)習(xí)PHP:初學(xué)者指南 Jul 18, 2025 am 04:54 AM

易於效率,啟動(dòng)啟動(dòng)tingupalocalserverenverenvirestoolslikexamppandacodeeditorlikevscode.1)installxamppforapache,mysql,andphp.2)uscodeeditorforsyntaxssupport.3)

See all articles