国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 后端開發(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 進行靜態(tài)代碼分析,那么當(dāng)您升級到 Laravel 11.x.

在使用

PHPStan 全新安裝 Laravel 時,第一次運行 ./vendor/bin/phpstan 時會拋出以下錯誤:

 ------ -----------------------------------------------------------------------------------
  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)在有一個

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

/**
 * @template TFactory of \Illuminate\Database\Eloquent\Factories\Factory
 */
trait HasFactory
{
    ...
}
雖然不建議這樣做,但只需將這些代碼行添加到您的 phpstan.neon 文件即可忽略此類錯誤:


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

什么是泛型?

編程中的泛型是指允許您編寫可處理多種數(shù)據(jù)類型的代碼的功能。您無需為每種數(shù)據(jù)類型編寫單獨的代碼,而是可以編寫一段通用的代碼,該代碼可以在保持類型安全的同時對各種類型進行操作,這與使用混合或?qū)ο蟮韧ㄓ妙愋筒煌?p>

采用

Laravel 10 中的 IlluminateDatabaseConcernsBuildsQueries::first 方法,它可以返回 Model 的實例、通用對象、像 IlluminateDatabaseEloquentBuilder 一樣使用它的類的實例或 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 標簽 @template、@template-covariant、@template-contravariant、@extends、@implements 和@使用。

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

類型參數(shù)定義的。PHPDocs中,我們使用@template標簽對它們進行注釋。類型參數(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 方法為例:

  • 它定義了一個類型參數(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
 ------ -----------------------------------------------------------------------------------

如果您隨后調(diào)用 $request→validated()→enum('status', OrderStatus::class),PHPStan 將知道您正在獲取 OrderStatus 對象或 null!

通用類

泛型類允許創(chuàng)建可以對任何數(shù)據(jù)類型進行操作的類,同時確保類型安全。它們允許使用特定類型的占位符來定義類,稍后可以在類實例化時替換該占位符。

Laravel 源代碼中的一個很好的例子是 IlluminateDatabaseEloquentBuilder 類:

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

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

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

parameters:
    ignoreErrors:
        -
            identifier: missingType.generics

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

通用接口

通用接口并沒有那么不同。 IlluminateContractsSupportArrayable 是通用接口的示例

/**
 * 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();
}

該接口定義了兩個類型參數(shù):array-key類型的TKey(可以是int或string)和TValue。這兩個參數(shù)用于定義 toArray 函數(shù)的返回類型。這是一個例子:

<?php

namespace Illuminate\Database\Eloquent;

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

用戶類實現(xiàn) Arrayable 接口,并指定 Tkey 類型為 int,TValue 類型為 string。

通用特征

我們在本文開頭的錯誤中遇到了 IlluminateDatabaseEloquentFactoriesHasFactory 特征。讓我們仔細看看:

/**
 * @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 定義了一個類型參數(shù) TFactory,它綁定到 IlluminateDatabaseEloquentFactoriesFactory 的子類。那么如何修復(fù)這個錯誤呢?

使用 Trait 時必須指定 TFactory 類型。因此,HasFactory 特征的 use 語句需要使用 PHPDocs @use:
進行注釋

<?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);
    }
}

保持通用性

擴展類、實現(xiàn)接口或使用特征時,可以保持子類中的通用性。

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

我們將使用 IlluminateDatabaseConcernsBuildsQueries 通用特征作為示例,

它定義了一個類型參數(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ā)人員在代碼中實現(xiàn)類似泛型的功能。通過利用 PHPDocs、參數(shù)化類和接口,您可以創(chuàng)建更靈活和類型安全的應(yīng)用程序,從而提高代碼的可重用性和可維護性。隨著 PHP 的不斷發(fā)展,社區(qū)對類型安全和靜態(tài)分析的日益關(guān)注可能會帶來更強大的泛型實現(xiàn)解決方案。接受這些實踐不僅可以提高您的編碼技能,還有助于開發(fā)經(jīng)得起時間考驗的高質(zhì)量軟件。

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

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

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

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

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

對基于PHP的API進行版本控制的最佳實踐是什么? 對基于PHP的API進行版本控制的最佳實踐是什么? Jun 14, 2025 am 12:27 AM

基于toversionaphp,useUrl deuseUrl specteringforclarityAndEsofRouting,單獨的codetoavoidConflicts,dremecateOldVersionswithClearCommunication,andConsiderCustomHeadeSerlySerallyWhennEnncelsy.startbyplacingtheversionIntheUrl(E.G.,epi/api/v

如何在PHP中實施身份驗證和授權(quán)? 如何在PHP中實施身份驗證和授權(quán)? Jun 20, 2025 am 01:03 AM

tosecurelyhandleauthenticationandationallizationInphp,lofterTheSesteps:1.AlwaysHashPasswordSwithPassword_hash()andverifyusingspasspassword_verify(),usepreparedStatatementStopreventsqlineptions,andStoreSeruserDatain usseruserDatain $ _sessiveferterlogin.2.implementrole-2.imaccessccsccccccccccccccccccccccccc.

PHP中的程序和面向?qū)ο蟮木幊谭独g有什么區(qū)別? PHP中的程序和面向?qū)ο蟮木幊谭独g有什么區(qū)別? Jun 14, 2025 am 12:25 AM

procemal and object-tiriendedprogromming(oop)inphpdiffersimplessintustructure,可重復(fù)使用性和datahandling.1.procedural-Progrogursmingusesfunctimesfunctionsormanized sequalized sequalized sequiential,poiperforsmallscripts.2.OpporganizesCodeOrganizescodeOdeIntsocloceSandObjects,ModelingReal-Worlden-Worlden

PHP中有哪些弱參考(弱圖),何時有用? PHP中有哪些弱參考(弱圖),何時有用? Jun 14, 2025 am 12:25 AM

PHPdoesnothaveabuilt-inWeakMapbutoffersWeakReferenceforsimilarfunctionality.1.WeakReferenceallowsholdingreferenceswithoutpreventinggarbagecollection.2.Itisusefulforcaching,eventlisteners,andmetadatawithoutaffectingobjectlifecycles.3.YoucansimulateaWe

如何在PHP中安全地處理文件上傳? 如何在PHP中安全地處理文件上傳? Jun 19, 2025 am 01:05 AM

要安全處理PHP中的文件上傳,核心在于驗證文件類型、重命名文件并限制權(quán)限。1.使用finfo_file()檢查真實MIME類型,僅允許特定類型如image/jpeg;2.用uniqid()生成隨機文件名,存儲至非Web根目錄;3.通過php.ini和HTML表單限制文件大小,設(shè)置目錄權(quán)限為0755;4.使用ClamAV掃描惡意軟件,增強安全性。這些步驟有效防止安全漏洞,確保文件上傳過程安全可靠。

如何與PHP的NOSQL數(shù)據(jù)庫(例如MongoDB,Redis)進行交互? 如何與PHP的NOSQL數(shù)據(jù)庫(例如MongoDB,Redis)進行交互? Jun 19, 2025 am 01:07 AM

是的,PHP可以通過特定擴展或庫與MongoDB和Redis等NoSQL數(shù)據(jù)庫交互。首先,使用MongoDBPHP驅(qū)動(通過PECL或Composer安裝)創(chuàng)建客戶端實例并操作數(shù)據(jù)庫及集合,支持插入、查詢、聚合等操作;其次,使用Predis庫或phpredis擴展連接Redis,執(zhí)行鍵值設(shè)置與獲取,推薦phpredis用于高性能場景,Predis則便于快速部署;兩者均適用于生產(chǎn)環(huán)境且文檔完善。

PHP中==(松散比較)和===(嚴格的比較)之間有什么區(qū)別? PHP中==(松散比較)和===(嚴格的比較)之間有什么區(qū)別? Jun 19, 2025 am 01:07 AM

在PHP中,==與===的主要區(qū)別在于類型檢查的嚴格程度。==在比較前會進行類型轉(zhuǎn)換,例如5=="5"返回true,而===要求值和類型都相同才會返回true,例如5==="5"返回false。使用場景上,===更安全應(yīng)優(yōu)先使用,==僅在需要類型轉(zhuǎn)換時使用。

如何在PHP( - , *, /,%)中執(zhí)行算術(shù)操作? 如何在PHP( - , *, /,%)中執(zhí)行算術(shù)操作? Jun 19, 2025 pm 05:13 PM

PHP中使用基本數(shù)學(xué)運算的方法如下:1.加法用 號,支持整數(shù)和浮點數(shù),也可用于變量,字符串?dāng)?shù)字會自動轉(zhuǎn)換但不推薦依賴;2.減法用-號,變量同理,類型轉(zhuǎn)換同樣適用;3.乘法用*號,適用于數(shù)字及類似字符串;4.除法用/號,需避免除以零,并注意結(jié)果可能是浮點數(shù);5.取模用%號,可用于判斷奇偶數(shù),處理負數(shù)時余數(shù)符號與被除數(shù)一致。正確使用這些運算符的關(guān)鍵在于確保數(shù)據(jù)類型清晰并處理好邊界情況。

See all articles