매직메소드란? 라라벨에서는 어떻게 사용하나요? 다음 글에서는 Laravel에서 PHP 매직 메소드를 적용하는 방법을 소개하겠습니다. 도움이 되길 바랍니다.
Laravel은 PHP를 완전히 새로운 수준으로 끌어올려 다음 프로젝트를 위한 뛰어난 개발 경험(DX)을 제공합니다. 그러므로 어떤 사람들은 그것을 "마법"이라고 부릅니다.
오늘은 Laravel의 Magic Method 트릭을 보여드리겠습니다.
매직 메서드는 Laravel에만 있는 것이 아니라 모든 PHP 애플리케이션에서 사용할 수 있다는 점을 이해하는 것이 중요합니다. Laravel은 매직 메소드에 대한 가장 흥미로운 사용 사례를 가지고 있습니다.
Magic 메서드는 클래스에 추가 기능을 구현하는 메서드를 제공하는 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
메소드를 알아야 합니다. 그래서 당신은 마법의 방법을 사용해 왔습니다. __construct
方法,这是一个魔术方法。所以您一直在使用魔术方法。
您还注意到,所有的魔术的方法都是以“__”为前缀的。
今天,我们不会深入研究这些方法,而只会深入了解整个Laravel代码库中使用的那些有趣的方法。如果其他人对此感兴趣,请随时查看下面的文档?
PHP: Méthodes magiques - Manual
<span style="font-size: 16px;">__get()</span>
Laravel中的模型非常特别。它们不将属性数据存储为类的直接属性,而是存储在protected $attributes
属性中,该属性是模型所保存的所有数据的相关数组。
让我们看看简单的PHP类和Laravel模型访问属性的区别。
<?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'
我们可以看到,上面的PHP和Laravel类的行为完全相同。
然而,在Laravel的例子中,属性不像普通PHP那样存储,而是集中在一个名为$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;
有更多的事情在幕后发生。如果你想更多地了解 Laravel 的模型是如何确切地使用 __get
的,你可以查看下面的源代码。
<span style="font-size: 16px;">__set()</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'
现在我们开始!我们在Laravel中成功实施了__ get
和__ set
<span style="font-size: 16px;">__get()🎜</span>
🎜 🎜🎜Laravel의 모델은 매우 특별합니다. 속성 데이터를 클래스의 직접적인 속성으로 저장하지 않고, 모델이 보유한 모든 데이터의 연관 배열인 protected $attributes
속성에 저장합니다. 🎜🎜간단한 PHP 클래스와 Laravel 모델 액세스 속성의 차이점을 살펴보겠습니다. 🎜<?php class NormalUser { public $firstName = 'Alice'; public $lastName = 'Bob'; } $normalUser = new NormalUser; $normalUser->fullName(); // 由于没有声明 "fullName" 方法,这将会抛出错误
<?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”
$attributes
라는 속성에 집중되어 있습니다. 여전히 올바른 데이터에 액세스할 수 있었지만 어떻게 🎜🎜이 모든 것이 _get
매직 메서드 덕분에 가능할까요? 간단한 예제를 직접 구현해 보겠습니다. 🎜rreee🎜우리가 해냈어! ?🎜🎜매직 메소드 _get
는 클래스에서 이름이 일치하는 속성을 찾을 수 없는 경우에만 호출된다는 점에 유의해야 합니다. 이는 PHP가 클래스에서 액세스되는 속성을 찾을 수 없을 때 호출되는 대체 메서드입니다. 따라서 다음 예에서는 매직 메서드 _get
가 전혀 호출되지 않습니다. 🎜rrreee🎜 뒤에서는 더 많은 일이 벌어지고 있습니다. Laravel의 모델이 __get
을 정확히 어떻게 사용하는지 더 알고 싶으시면 아래 소스 코드를 확인해 보세요. 🎜🎜laravel/framework🎜🎜🎜 🎜 🎜🎜<span style="font-size: 16px;">__set()🎜</span>
🎜🎜🎜설정하려는 속성이 선언되지 않은 경우 매직 메소드 _set를 사용하세요. 클래스 코드>에서. 일반 PHP 클래스와 Laravel 모델의 차이점을 다시 살펴보겠습니다. 🎜rrreeerrreee🎜보시다시피, 이 예에서 우리는 클래스에 실제로 존재하지 않지만 <code>$attributes
속성에 있는 Bob
의 값에 영향을 주려고 시도하고 있습니다. . 마법의 메소드 __ set
를 사용해 봅시다🎜rrreee🎜이제 시작하겠습니다! 우리는 Laravel에서 __ get
및 __ set
매직 메소드의 기본 사용법을 성공적으로 구현했습니다! 단 몇 줄의 코드만으로 이를 수행할 수 있습니다! 🎜🎜이 마법 방법은 너무 많은 세부 사항을 다루지 않고 가능한 한 간단하다는 점을 기억하십시오. 왜냐하면 단순히 사용 사례만이 아니라 그 이상이 있기 때문입니다. 작동 방식이 궁금하다면 몇 가지 탐색을 해보시기 바랍니다. 너 자신을 위해! (질문이 있으시면 언제든지 Twitter로 연락하실 수도 있습니다.) 🎜🎜다시 한 번 더 자세히 알고 싶으시면 여기에 소스 코드 링크가 있습니다. 🎜🎜🎜laravel/framework🎜🎜🎜마지막으로 넘어가겠습니다. 역시 가장 흥미로운 점! ?🎜<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 중국어 웹사이트의 기타 관련 기사를 참조하세요!