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

長URL(通常用關鍵字和跟踪參數都混亂)可以阻止訪問者。 URL縮短腳本提供了解決方案,創建了簡潔的鏈接,非常適合社交媒體和其他平台。 這些腳本對於單個網站很有價值

在Facebook在2012年通過Facebook備受矚目的收購之後,Instagram採用了兩套API供第三方使用。這些是Instagram Graph API和Instagram Basic Display API。作為開發人員建立一個需要信息的應用程序

Laravel使用其直觀的閃存方法簡化了處理臨時會話數據。這非常適合在您的應用程序中顯示簡短的消息,警報或通知。 默認情況下,數據僅針對後續請求: $請求 -

這是有關用Laravel後端構建React應用程序的系列的第二個也是最後一部分。在該系列的第一部分中,我們使用Laravel為基本的產品上市應用程序創建了一個RESTFUL API。在本教程中,我們將成為開發人員

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显著减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

PHP客戶端URL(curl)擴展是開發人員的強大工具,可以與遠程服務器和REST API無縫交互。通過利用Libcurl(備受尊敬的多協議文件傳輸庫),PHP curl促進了有效的執行

您是否想為客戶最緊迫的問題提供實時的即時解決方案? 實時聊天使您可以與客戶進行實時對話,並立即解決他們的問題。它允許您為您的自定義提供更快的服務

2025年的PHP景觀調查調查了當前的PHP發展趨勢。 它探討了框架用法,部署方法和挑戰,旨在為開發人員和企業提供見解。 該調查預計現代PHP Versio的增長


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版
中文版,非常好用

記事本++7.3.1
好用且免費的程式碼編輯器

Dreamweaver Mac版
視覺化網頁開發工具