什麼是魔術方法?如何在 Laravel 的應用?以下這篇文章跟大家介紹PHP 魔術方法在 Laravel應用的方法,希望對大家有幫助!
Laravel將PHP應用到了一個全新的水平,為您打造下一個專案提供了出色的開發體驗(DX)。因此,有些人稱之為“魔術”。
今天,我將向您展示Laravel的一個技巧,魔術方法。
重要的是,要了解魔術方法並不是Laravel獨有的,而是可以在任何PHP應用中使用。 Laravel恰好有一些最有趣的魔術方法用例。
魔術方法是在PHP中聲明的任何類別中都可以使用的方法,它提供了在類別中實作附加功能的方法。
這裡有一個很好的定義:
魔術方法永遠不會被程式設計師呼叫-實際上,PHP將在後台呼叫該方法。這就是為什麼它們被稱為“魔術”方法——因為它們從來沒有被直接調用,它們允許程式設計師做一些非常強大的是事情。
總共有15中魔術方法:
class MyClass { public function __construct() {} public function __destruct() {} public function __call() {} public function __callStatic() {} public function __get() {} public function __set() {} public function __isset() {} public function __unset() {} public function __sleep() {} public function __wakeup() {} public function __toString() {} public function __invoke() {} public function __set_state() {} public function __clone() {} public function __debuginfo() {} }
如果您用PHP做過一些物件導向的編程,那麼您一定知道__construct
方法,這是一個魔術方法。所以您一直在使用魔術方法。
您也注意到,所有的魔術的方法都是以「__」為前綴的。
今天,我們不會深入研究這些方法,而只會深入了解整個Laravel程式碼庫中使用的那些有趣的方法。如果其他人對此感興趣,請隨時查看下面的文檔?
##PHP: Méthodes magiques - Manual
#__get()<span style="font-size: 16px;"></span>
protected $attributes 屬性中,該屬性是模型所保存的所有資料的相關陣列。
<?php /** * PHP中的普通用户类(非Laravel)将只是一个具有上述属性的类 */ class NormalUser { public $firstName = 'Alice'; } $normalUser = new NormalUser; $normalUser->firstName; // 将返回'Alice'
<?php namespace App; use Illuminate\Database\Eloquent\Model; /** * Laravel中的一个user类 */ class LaravelUser extends Model { /** * 注意,我们将所有属性数据存储在一个单独的数组中 */ protected $attributes = [ 'firstName' => 'Alice', ]; } $laravelUser = new LaravelUser; $laravelUser->firstName; // 依然返回'Alice'
$attributes的屬性中。我們仍然設法存取正確的數據,但是如何存取呢?
_get魔術方法。讓我們自己嘗試實作一個簡單的例子。
<?php class NormalUser { /** * 像在Laravel中那样声明属性 */ protected $attributes = [ 'firstName' => 'Alice', ]; /** * __get 函数接收一个参数 * 它将会是你想要访问的属性名 * 在这个例子中是 $key = "firstName" */ public function __get(string $key) { return $this->attributes[$key]; } } $normalUser = new NormalUser; $normalUser->firstName; // 将会返回 'Alice'
_get。這是一種後備方法,當PHP在類別中找不到所存取的屬性時呼叫。因此,在下面的範例中,根本不會呼叫魔術方法
_get。
<?php class NormalUser { public $firstName = 'Bob'; protected $attributes = [ 'firstName' => 'Alice', ]; public function __get($key) { return $this->attributes[$key]; } } $normalUser = new NormalUser; /** * 由于类中存在该属性,将会返回 Bob * 所以该例子中没有调用到魔术方法__get */ $normalUser->firstName;
__get 的,你可以查看下面的原始程式碼。
#__set()<span style="font-size: 16px;"></span>
_set。讓我們再來看看normal PHP類別和Laravel中model模型的差異。
<?php class NormalUser { public $firstName = 'Alice'; } $normalUser = new NormalUser; $normalUser->firstName = 'Bob'; $normalUser->firstName; // Will return 'Bob'
<?php namespace App; use Illuminate\Database\Eloquent\Model; class LaravelUser extends Model { protected $attributes = [ 'firstName' => 'Alice', ]; } $laravelUser = new LaravelUser; $laravelUser->firstName = 'Bob'; $laravelUser->firstName; // Will return 'Bob' as well
Bob的值,該值在類別中實際上不存在但位於屬性
$ attributes中。讓我們嘗試使用魔術方法
__ set
<?php class NormalUser { public $attributes = [ 'firstName' => 'Alice', ]; /** * The magic method __set receives the $name you want to affect the value on * and the value */ public function __set($key, $value) { $this->attributes[$key] = $value; } } $normalUser = new NormalUser; $normalUser->firstName = 'Bob'; /** * As we don't have the __get magic method define in this example for simplicity sake, * we will access the $attributes directly */ $normalUser->attributes['firstName']; // Will return 'Bob'
__ get和
__ set魔術方法的基本用法!他們只需幾行程式碼就能完成!
<span style="font-size: 16px;">__call()</span>
& <span style="font-size: 16px;">__callStatic()</span>
当调用的方法在类中找不到时,__call()
会被调用。 在laravel中,该魔术方法方法使宏在 php 中成为可能。
我不会深入讨论宏的所有细节,但如果您感兴趣,这里有一篇很好的文章解释了如何在 Laravel 应用程序中使用它们?
让我们试着看看如何编写一个简单的宏示例。
<?php class NormalUser { public $firstName = 'Alice'; public $lastName = 'Bob'; } $normalUser = new NormalUser; $normalUser->fullName(); // 由于没有声明 "fullName" 方法,这将会抛出错误
使用 __call
,可以定义一个包含闭包函数的数组,在我们开发时可以程序化地添加到应用里。
<?php class NormalUser { public $firstName = 'Alice'; public $lastName = 'Bob'; /** * 将我们的宏初始化为一个空数组,后面再赋值 */ public static $macros = []; /** * 定义一个添加新宏的方法 * 第一个参数是我们想要定义的宏的名字 * 第二个参数是调用宏时将会被执行的闭包函数 */ public static function addMacro($name, $macro) { static::$macros[$name] = $macro; } /** * "__call" 接收两个参数, * $name 是被调用的函数名称,比如 “fullName” * $arguments 是传递给函数的所有参数,这里我们使用了一个空数组,因为我们的函数不用传参 */ public function __call(string $name, array $arguments) { /** * 通过名称获取到宏 */ $macro = static::$macros[$name]; /** * 然后通过参数执行宏 * 备注:调用之前,我们需要将闭包绑定到 “$this”,从而使宏方法在同样的上下文中执行 */ return call_user_func_array($macro->bindTo($this, static::class), $arguments); } } $normalUser = new NormalUser; $normalUser->fullName(); // 这里会中断,因为我们既没有定义 “fullName” 宏,也没有 “fullName” 方法存在。 /** * 添加 “fullName” 宏方法 */ NormalUser::addMacro('fullName', function () { return $this->firstName.' '.$this->lastName; }); $normalUser->fullName(); // 现在,返回 “Alice Bob”
宏要比那个复杂一些,但是我们设法使用 __call
魔术方法来创建一个宏的简单工作版本。
除了对于静态方法, __callStatic
和 __call
是完全一样的。
如果你打算自己再深入研究,这里有宏的特性源代码。
所以说码农们,当你第一次用 Laravel 会感觉它神奇是对的,但是通过深入查看源代码,你会理解魔法是如何在场景背后施展的。
就像现实生活中的魔法,没有道理的事情是不会发生的,在代码中就更加是了。程序运行的背后总是有着一行代码在执行,只不过需要你去发现它。
英文原文地址:https://dev.to/stvnyung/laravel-greatest-trick-revealed-magic-methods-31om
译文地址:https://learnku.com/laravel/t/40926
【相关推荐:laravel视频教程】
以上是什麼是魔術方法?如何在 Laravel 中使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!