首页 php框架 Laravel 什么是魔术方法?如何在 Laravel 中使用

什么是魔术方法?如何在 Laravel 中使用

Sep 26, 2022 pm 08:21 PM
php laravel 魔术方法

什么是魔术方法?如何在 Laravel 中的应用?下面本篇文章给大家介绍一下PHP 魔术方法在 Laravel中应用的方法,希望对大家有所帮助!

什么是魔术方法?如何在 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

Laravel是如何使用的魔术方法

<span style="font-size: 16px;">__get()</span>

Laravel中的模型非常特别。它们不将属性数据存储为类的直接属性,而是存储在protected $attributes 属性中,该属性是模型所保存的所有数据的相关数组。

让我们看看简单的PHP类和Laravel模型访问属性的区别。

<?php

/**
 * PHP中的普通用户类(非Laravel)将只是一个具有上述属性的类
 */
class NormalUser
{
    public $firstName = &#39;Alice&#39;;
}

$normalUser = new NormalUser;

$normalUser->firstName; // 将返回'Alice'
登录后复制
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

/**
 * Laravel中的一个user类
 */
class LaravelUser extends Model
{
    /**
     * 注意,我们将所有属性数据存储在一个单独的数组中
     */
    protected $attributes = [
        &#39;firstName&#39; => 'Alice',
    ];
}

$laravelUser = new LaravelUser;

$laravelUser->firstName; // 依然返回'Alice'
登录后复制

我们可以看到,上面的PHP和Laravel类的行为完全相同。

然而,在Laravel的例子中,属性不像普通PHP那样存储,而是集中在一个名为$attributes的属性中。我们仍然设法访问正确的数据,但是如何访问呢?

这一切都是可能的,这是因为_get魔术方法。让我们自己尝试实现一个简单的例子。

<?php

class NormalUser
{
    /**
     * 像在Laravel中那样声明属性
     */
    protected $attributes = [
        &#39;firstName&#39; => '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 = &#39;Bob&#39;;

    protected $attributes = [
        &#39;firstName&#39; => 'Alice',
    ];

    public function __get($key)
    {
        return $this->attributes[$key];
    }
}

$normalUser = new NormalUser;

/**
 * 由于类中存在该属性,将会返回 Bob
 * 所以该例子中没有调用到魔术方法__get
 */
$normalUser->firstName;
登录后复制

有更多的事情在幕后发生。如果你想更多地了解 Laravel 的模型是如何确切地使用 __get 的,你可以查看下面的源代码。

laravel/framework

<span style="font-size: 16px;">__set()</span>

当试图设置的属性没有在类中声明时,使用魔术方法_set。让我们再次看看normal PHP类和Laravel中model模型的区别。

<?php

class NormalUser
{
    public $firstName = &#39;Alice&#39;;
}

$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 = [
        &#39;firstName&#39; => 'Alice',
    ];
}

$laravelUser = new LaravelUser;

$laravelUser->firstName = 'Bob';

$laravelUser->firstName; // Will return 'Bob' as well
登录后复制

如我们所见,在此示例中,我们仍然尝试影响Bob的值,该值在类中实际上不存在但位于属性$ attributes中。让我们尝试使用魔术方法__ set

<?php

class NormalUser
{
    public $attributes = [
        &#39;firstName&#39; => '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魔术方法的基本用法!他们只需几行代码就能完成!

请记住,这些魔术方法尽可能简单,而不必涉及太多细节,因为除了那些还有更多而不仅仅是用例,如果您对它的工作原理感到好奇,我邀请您亲自做一些探索! (如果您有任何疑问,也可以随时在Twitter上与我联系)

同样,如果您想进一步挖掘,请在此处链接到源代码

laravel/framework

让我们继续最后一个也是最有趣的一个事! ?

<span style="font-size: 16px;">__call()</span> & <span style="font-size: 16px;">__callStatic()</span>

当调用的方法在类中找不到时,__call()会被调用。 在laravel中,该魔术方法方法使宏在 php 中成为可能。

我不会深入讨论宏的所有细节,但如果您感兴趣,这里有一篇很好的文章解释了如何在 Laravel 应用程序中使用它们?

The Magic of Laravel Macros

让我们试着看看如何编写一个简单的宏示例。

<?php

class NormalUser
{
    public $firstName = &#39;Alice&#39;;

    public $lastName = &#39;Bob&#39;;
}

$normalUser = new NormalUser;

$normalUser->fullName(); // 由于没有声明 "fullName" 方法,这将会抛出错误
登录后复制

使用 __call ,可以定义一个包含闭包函数的数组,在我们开发时可以程序化地添加到应用里。

<?php

class NormalUser
{
    public $firstName = &#39;Alice&#39;;

    public $lastName = &#39;Bob&#39;;

    /**
     * 将我们的宏初始化为一个空数组,后面再赋值
     */
    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/framework

总结

所以说码农们,当你第一次用 Laravel 会感觉它神奇是对的,但是通过深入查看源代码,你会理解魔法是如何在场景背后施展的。

就像现实生活中的魔法,没有道理的事情是不会发生的,在代码中就更加是了。程序运行的背后总是有着一行代码在执行,只不过需要你去发现它。

英文原文地址:https://dev.to/stvnyung/laravel-greatest-trick-revealed-magic-methods-31om

译文地址:https://learnku.com/laravel/t/40926

【相关推荐:laravel视频教程

以上是什么是魔术方法?如何在 Laravel 中使用的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热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

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

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1669
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1273
29
C# 教程
1256
24
如果session_start()被多次调用会发生什么? 如果session_start()被多次调用会发生什么? Apr 25, 2025 am 12:06 AM

多次调用session_start()会导致警告信息和可能的数据覆盖。1)PHP会发出警告,提示session已启动。2)可能导致session数据意外覆盖。3)使用session_status()检查session状态,避免重复调用。

作曲家:通过AI的帮助开发PHP 作曲家:通过AI的帮助开发PHP Apr 29, 2025 am 12:27 AM

AI可以帮助优化Composer的使用,具体方法包括:1.依赖管理优化:AI分析依赖关系,建议最佳版本组合,减少冲突。2.自动化代码生成:AI生成符合最佳实践的composer.json文件。3.代码质量提升:AI检测潜在问题,提供优化建议,提高代码质量。这些方法通过机器学习和自然语言处理技术实现,帮助开发者提高效率和代码质量。

session_start()函数的意义是什么? session_start()函数的意义是什么? May 03, 2025 am 12:18 AM

session_start()iscucialinphpformanagingusersessions.1)ItInitiateSanewsessionifnoneexists,2)resumesanexistingsessions,and3)setsasesessionCookieforContinuityActinuityAccontinuityAcconActInityAcconActInityAcconAccRequests,EnablingApplicationsApplicationsLikeUseAppericationLikeUseAthenticationalticationaltication and PersersonalizedContentent。

哪些数据库版本与最新的Laravel兼容? 哪些数据库版本与最新的Laravel兼容? Apr 25, 2025 am 12:25 AM

最新版本的Laravel10与MySQL5.7及以上、PostgreSQL9.6及以上、SQLite3.8.8及以上、SQLServer2017及以上兼容。这些版本选择是因为它们支持Laravel的ORM功能,如MySQL5.7的JSON数据类型,提升了查询和存储效率。

php框架laravel和yii区别是什么 php框架laravel和yii区别是什么 Apr 30, 2025 pm 02:24 PM

Laravel和Yii的主要区别在于设计理念、功能特性和使用场景。1.Laravel注重开发的简洁和愉悦,提供丰富的功能如EloquentORM和Artisan工具,适合快速开发和初学者。2.Yii强调性能和效率,适用于高负载应用,提供高效的ActiveRecord和缓存系统,但学习曲线较陡。

H5:HTML5的关键改进 H5:HTML5的关键改进 Apr 28, 2025 am 12:26 AM

HTML5带来了五个关键改进:1.语义化标签提升了代码清晰度和SEO效果;2.多媒体支持简化了视频和音频嵌入;3.表单增强简化了验证;4.离线与本地存储提高了用户体验;5.画布与图形功能增强了网页的可视化效果。

Laravel 最佳扩展包推荐:2024 年必备工具 Laravel 最佳扩展包推荐:2024 年必备工具 Apr 30, 2025 pm 02:18 PM

2024年必备的Laravel扩展包包括:1.LaravelDebugbar,用于监控和调试代码;2.LaravelTelescope,提供详细的应用监控;3.LaravelHorizon,管理Redis队列任务。这些扩展包能提升开发效率和应用性能。

如何使用MySQL的函数进行数据处理和计算 如何使用MySQL的函数进行数据处理和计算 Apr 29, 2025 pm 04:21 PM

MySQL函数可用于数据处理和计算。1.基本用法包括字符串处理、日期计算和数学运算。2.高级用法涉及结合多个函数实现复杂操作。3.性能优化需避免在WHERE子句中使用函数,并使用GROUPBY和临时表。

See all articles