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

首頁(yè) 後端開(kāi)發(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
但是,泛型並不難理解,所以讓我們開(kāi)始吧!

什麼是泛型?

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

採(cǎi)用

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();
}
泛型語(yǔ)法

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)鍵字限制可以使用哪些類型來(lái)取代帶有上限的類型參數(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)位符來(lái)定義類,稍後可以在類實(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)圍來(lái)根據(jù)訂單狀態(tài)過(guò)濾訂單。範(fàn)圍方法應(yīng)指定 TModel 類型

parameters:
    ignoreErrors:
        -
            identifier: missingType.generics

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

通用介面

通用介面並沒(méi)有那麼不同。 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è)诒疚拈_(kāi)頭的錯(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 語(yǔ)句需要使用 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í),可以保持子類別中的通用性。

透過(guò)在子類別上方定義相同的類型參數(shù)並將其傳遞給 @extends、@implements 和 @use 標(biāo)籤來(lái)實(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 類別使用此特徵,但透過(guò)向其傳遞 TModel 參數(shù)類型來(lái)保持其通用性?,F(xiàn)在由客戶端程式碼來(lái)指定 TModel 的類型,從而在 BuildsQueries 特徵中指定 TValue。

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

最後的想法

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

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

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

對(duì)基於PHP的API進(jìn)行版本控制的最佳實(shí)踐是什麼? 對(duì)基於PHP的API進(jìn)行版本控制的最佳實(shí)踐是什麼? Jun 14, 2025 am 12:27 AM

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

如何在PHP中實(shí)施身份驗(yàn)證和授權(quán)? 如何在PHP中實(shí)施身份驗(yàn)證和授權(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ū)ο蟮木幊坦?fàn)例之間有什麼區(qū)別? PHP中的程序和麵向?qū)ο蟮木幊坦?fàn)例之間有什麼區(qū)別? Jun 14, 2025 am 12:25 AM

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

PHP中有哪些弱參考(弱圖),何時(shí)有用? PHP中有哪些弱參考(弱圖),何時(shí)有用? 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中的文件上傳,核心在於驗(yàn)證文件類型、重命名文件並限制權(quán)限。 1.使用finfo_file()檢查真實(shí)MIME類型,僅允許特定類型如image/jpeg;2.用uniqid()生成隨機(jī)文件名,存儲(chǔ)至非Web根目錄;3.通過(guò)php.ini和HTML表單限製文件大小,設(shè)置目錄權(quán)限為0755;4.使用ClamAV掃描惡意軟件,增強(qiáng)安全性。這些步驟有效防止安全漏洞,確保文件上傳過(guò)程安全可靠。

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

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

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

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

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

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

See all articles