搜尋
首頁後端開發php教程Laravel 底層 - 一些宏

Laravel 底層 - 一些宏

Nov 07, 2024 pm 01:13 PM

Laravel Under The Hood - A Little Bit of Macros

你好 ?

您是否經常希望獲得一個集合或字串助手中不存在的方法?你開始連結方法,結果發現其中一個方法遺失了,結果卻碰壁了。老實說,這是可以理解的;你知道,框架是一刀切的東西。我多次發現自己處於這種情況。每次,在深入研究如何擴展框架之前,我都會檢查我想要擴展的內容是否可宏。但這意味著什麼?這正是我們將要探索的!

WTF 是宏嗎? ?

假設我們有這個 JWT:

$jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';

我們需要擷取標題:

str($jwt)
    ->before('.')
    ->fromBase64()
    ->fromJson(); // does not exist ?

//  BadMethodCallException  Method Illuminate\Support\Stringable::fromJson does not exist.

fromJson() 不存在?當然,人們可以簡單地這樣做:

json_decode(str($jwt)->before('.')->fromBase64());

但這有什麼樂趣呢?另外,這是我的文章?

所以,我們需要一個方法來擴充 Stringable 類別。有幾種方法可以做到這一點,但 Laravel 提前思考,它知道開發人員可能想要添加自訂方法,因此它使類別可宏,或者像我喜歡的那樣,可擴展。

如果您檢查 IlluminateSupportStringable 類,您會看到它使用 Macroable 特徵。

讓我們繼續擴展課程。在AppServiceProvider中,加入以下內容:

<?php namespace App\Providers;

use Illuminate\Support\Stringable;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Stringable::macro('fromJson', function (bool $associative = true) {
            return json_decode($this->value, $associative);
        });
    }
}

現在讓我們重新運行程式碼:

str($jwt)
    ->before('.')
    ->fromBase64()
    ->fromJson();

// ["alg" => "HS256", "typ" => "JWT"]

效果完美嗎?但現在,您可能想知道,這是如何運作的? $this->value 到底是什麼?哈利波特裡發生了什麼事?

揭開魔法的面紗?

我們知道Stringable類別使用Macroable特徵,它提供了macro()方法。讓我們仔細看看它的作用:

// src/Illuminate/Macroable/Traits/Macroable.php

/**
 * Register a custom macro.
 *
 * @param  string  $name
 * @param  object|callable  $macro
 *
 * @param-closure-this static  $macro
 *
 * @return void
 */
public static function macro($name, $macro)
{
    static::$macros[$name] = $macro;
}

這非常簡單,它只是將回調保存到靜態巨集數組中。現在,如果我們進一步檢查該特徵,我們會發現 __call 方法,每次呼叫不存在的方法時都會觸發方法。在我們的例子中,就是 fromJson()。讓我們深入了解:

/**
 * Dynamically handle calls to the class.
 *
 * @param  string  $method
 * @param  array  $parameters
 * @return mixed
 *
 * @throws \BadMethodCallException
 */
public function __call($method, $parameters)
{
    if (! static::hasMacro($method)) {
        throw new BadMethodCallException(sprintf(
            'Method %s::%s does not exist.', static::class, $method
        ));
    }

    $macro = static::$macros[$method];

    if ($macro instanceof Closure) {
        $macro = $macro->bindTo($this, static::class);
    }

    return $macro(...$parameters);
}

首先,它檢查巨集是否已註冊,fromJson() 就是這種情況,然後從巨集數組中取得回呼(或物件)。現在讓我們來看看魔術,如果巨集是閉包(如我們的例子),它會呼叫bindTo(),它本質上告訴閉包$this應該引用作為第一個參數傳遞的任何內容。在本例中,它是 Stringable 實例,它恰好具有 $value 屬性。

// $this here is the stringable
// $this inside the closure is now referencing the stringable class
$macro->bindTo($this, static::class);

這就是為什麼我們可以做 $this->value。

我們可以做得更好:Mixins?

我還想告訴你一件事!當我們多次擴展同一個類別時,服務提供者可能很快就會變得混亂。我們可以將所有自訂巨集提取到一個名為 Mixin 的類別中。

讓我們建立一個 StringableMixin:

$jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';

現在,在 AppServiceProvider 中,我們可以註冊這個 mixin:

str($jwt)
    ->before('.')
    ->fromBase64()
    ->fromJson(); // does not exist ?

//  BadMethodCallException  Method Illuminate\Support\Stringable::fromJson does not exist.

就是這樣!現在我們可以做:

json_decode(str($jwt)->before('.')->fromBase64());

基本上是一樣的,只是比較乾淨一點。

如果您對它的工作原理感到好奇,Macroable 特徵上的 mixin() 方法使用反射 API。它從 Mixin 類別中檢索所有公共方法,期望每個方法傳回一個閉包,然後將閉包註冊為宏,就像我們之前看到的那樣。

糟糕的 IDE?

嗯,正如您所看到的,有很多神奇的事情發生,IDE 不知道定義的巨集。如果您在團隊中工作,其他開發人員也不會知道這些宏,這不好。幸運的是,有一些工具可以幫助您做到這一點。 Laravel IDE 幫助程式包是一個免費開源選項。

您可以安裝該軟體包並產生 _ide_helper.php 文件,然後就可以開始了。

就這樣結束了..

我們的範例相當簡單,但是您可以將巨集推得更遠,因為 Laravel 附帶的大多數常見類別都是可巨集的。例如,您可以新增一個新的 apiResponse() 宏,或者您認為在應用程式邏輯中非常常見且重複次數過多的任何內容。但不要做得太過分。巨集增加了新的複雜性,在團隊中工作時,它們可能會令人困惑。

Soo,每當您感覺應用程式缺少某些內容,但框架本身沒有缺少某些內容時,請使用巨集?

以上是Laravel 底層 - 一些宏的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
PHP依賴注入容器:快速啟動PHP依賴注入容器:快速啟動May 13, 2025 am 12:11 AM

aphpdepentioncontiveContainerIsatoolThatManagesClassDeptions,增強codemodocultion,可驗證性和Maintainability.itactsasaceCentralHubForeatingingIndections,因此reducingTightCightTightCoupOulplingIndeSingantInting。

PHP中的依賴注入與服務定位器PHP中的依賴注入與服務定位器May 13, 2025 am 12:10 AM

選擇DependencyInjection(DI)用於大型應用,ServiceLocator適合小型項目或原型。 1)DI通過構造函數注入依賴,提高代碼的測試性和模塊化。 2)ServiceLocator通過中心註冊獲取服務,方便但可能導致代碼耦合度增加。

PHP性能優化策略。PHP性能優化策略。May 13, 2025 am 12:06 AM

phpapplicationscanbeoptimizedForsPeedAndeffificeby:1)啟用cacheInphp.ini,2)使用preparedStatatementSwithPdoforDatabasequesies,3)3)替換loopswitharray_filtaray_filteraray_maparray_mapfordataprocrocessing,4)conformentnginxasaseproxy,5)

PHP電子郵件驗證:確保正確發送電子郵件PHP電子郵件驗證:確保正確發送電子郵件May 13, 2025 am 12:06 AM

phpemailvalidation invoLvesthreesteps:1)格式化進行regulareXpressecthemailFormat; 2)dnsvalidationtoshethedomainhasavalidmxrecord; 3)

如何使PHP應用程序更快如何使PHP應用程序更快May 12, 2025 am 12:12 AM

tomakephpapplicationsfaster,關注台詞:1)useopcodeCachingLikeLikeLikeLikeLikePachetoStorePreciledScompiledScriptbyTecode.2)MinimimiedAtabaseSqueriSegrieSqueriSegeriSybysequeryCachingandeffeftExting.3)Leveragephp7 leveragephp7 leveragephp7 leveragephpphp7功能forbettercodeefficy.4)

PHP性能優化清單:立即提高速度PHP性能優化清單:立即提高速度May 12, 2025 am 12:07 AM

到ImprovephPapplicationspeed,關注台詞:1)啟用opcodeCachingwithapCutoredUcescriptexecutiontime.2)實現databasequerycachingingusingpdotominiminimizedatabasehits.3)usehttp/2tomultiplexrequlexrequestsandreduceconnection.4 limitesclection.4.4

PHP依賴注入:提高代碼可檢驗性PHP依賴注入:提高代碼可檢驗性May 12, 2025 am 12:03 AM

依赖注入(DI)通过显式传递依赖关系,显著提升了PHP代码的可测试性。1)DI解耦类与具体实现,使测试和维护更灵活。2)三种类型中,构造函数注入明确表达依赖,保持状态一致。3)使用DI容器管理复杂依赖,提升代码质量和开发效率。

PHP性能優化:數據庫查詢優化PHP性能優化:數據庫查詢優化May 12, 2025 am 12:02 AM

DatabasequeryoptimizationinPHPinvolvesseveralstrategiestoenhanceperformance.1)Selectonlynecessarycolumnstoreducedatatransfer.2)Useindexingtospeedupdataretrieval.3)Implementquerycachingtostoreresultsoffrequentqueries.4)Utilizepreparedstatementsforeffi

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱門文章

熱工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用