你好 ?
您是否经常希望获得一个集合或字符串助手中不存在的方法?你开始链接方法,结果发现其中一个方法丢失了,结果却碰壁了。老实说,这是可以理解的;你知道,框架是一刀切的东西。我多次发现自己处于这种情况。每次,在深入研究如何扩展框架之前,我都会检查我想要扩展的内容是否可宏。但这意味着什么?这正是我们将要探索的!
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中文网其他相关文章!

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

到ImprovephPapplicationspeed,关注台词:1)启用opcodeCachingwithapCutoredUcescriptexecutiontime.2)实现databasequerycachingusingpdotominiminimizedatabasehits.3)usehttp/2tomultiplexrequlexrequestsandredececonnection.4 limitsclection.4.4

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

databasequeryOptimizationinphpinvolVolVOLVESEVERSEVERSTRATEMIESOENHANCEPERANCE.1)SELECTONLYNLYNESSERSAYCOLUMNSTORMONTOUMTOUNSOUDSATATATATATATATATATATRANSFER.3)

phpisusedforsenderemailsduetoitsbuilt-inmail()函数andsupportiveLibrariesLikePhpMailerandSwiftMailer.1)usethemail()functionforbasicemails,butithasimails.2)butithasimimitations.2)

PHP性能瓶颈可以通过以下步骤解决:1)使用Xdebug或Blackfire进行性能分析,找出问题所在;2)优化数据库查询并使用缓存,如APCu;3)使用array_filter等高效函数优化数组操作;4)配置OPcache进行字节码缓存;5)优化前端,如减少HTTP请求和优化图片;6)持续监控和优化性能。通过这些方法,可以显着提升PHP应用的性能。

依赖性注射(DI)InphpisadesignPatternthatManages和ReducesClassDeptions,增强量产生性,可验证性和Maintainability.itallowspasspassingDepentenciesLikEdenceSeconnectionSeconnectionStoclasseconnectionStoclasseSasasasasareTers,interitationApertatingAeseritatingEaseTestingEasingEaseTeStingEasingAndScalability。

cachingimprovesphpermenceByStorcyResultSofComputationsorqucrouctationsorquctationsorquickretrieval,reducingServerLoadAndenHancingResponsetimes.feftectivestrategiesinclude:1)opcodecaching,whereStoresCompiledSinmememorytssinmemorytoskipcompliation; 2)datacaching datacachingsingMemccachingmcachingmcachings


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

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

禅工作室 13.0.1
功能强大的PHP集成开发环境

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript开发工具