Rumah  >  Artikel  >  rangka kerja php  >  Apakah kaedah sihir? Bagaimana untuk menggunakannya dalam Laravel

Apakah kaedah sihir? Bagaimana untuk menggunakannya dalam Laravel

青灯夜游
青灯夜游ke hadapan
2022-09-26 20:21:271890semak imbas

Apakah kaedah ajaib? Bagaimana untuk menggunakannya dalam Laravel? Artikel berikut akan memperkenalkan kepada anda cara menggunakan kaedah sihir PHP dalam Laravel. Saya harap ia akan membantu anda!

Apakah kaedah sihir? Bagaimana untuk menggunakannya dalam Laravel

Laravel membawa PHP ke tahap baharu, memberikan pengalaman pembangunan (DX) yang hebat untuk projek anda yang seterusnya. Oleh itu, sesetengah orang memanggilnya "sihir".

Hari ini, saya akan menunjukkan kepada anda helah dalam Laravel, iaitu Kaedah Sihir.

Apakah kaedah sihir?

Adalah penting untuk memahami bahawa kaedah ajaib bukan unik untuk Laravel tetapi boleh digunakan dalam mana-mana aplikasi PHP. Laravel kebetulan mempunyai beberapa kes penggunaan yang paling menarik untuk kaedah sihir.

Kaedah ajaib ialah kaedah yang tersedia dalam mana-mana kelas yang diisytiharkan dalam PHP yang menyediakan cara untuk melaksanakan fungsi tambahan dalam kelas.

Berikut ialah definisi yang baik:

Kaedah ajaib tidak akan pernah dipanggil oleh pengaturcara - sebenarnya, PHP akan memanggil kaedah di belakang tabir. Inilah sebabnya mengapa mereka dipanggil kaedah "ajaib" - kerana mereka tidak pernah dipanggil secara langsung, mereka membenarkan pengaturcara melakukan beberapa perkara yang sangat berkuasa.

Terdapat 15 kaedah ajaib secara keseluruhan:

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() {}
}

Jika anda telah melakukan beberapa pengaturcaraan berorientasikan objek dengan PHP, maka anda mesti tahu kaedah __construct, iaitu kaedah silap mata. Jadi anda telah menggunakan kaedah sihir.

Anda juga perasan bahawa semua kaedah sihir diawali dengan "__".

Hari ini kita tidak akan menyelidiki kaedah ini, tetapi hanya kaedah menarik yang digunakan di seluruh pangkalan kod Laravel. Jika sesiapa lagi berminat, sila semak dokumentasi di bawah?

PHP: Méthodes magiques - Manual

Laravel ialah Cara menggunakan kaedah ajaib

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

Model dalam Laravel sangat istimewa. Mereka tidak menyimpan data atribut sebagai sifat langsung kelas, tetapi dalam atribut protected $attributes, yang merupakan tatasusunan bersekutu semua data yang dipegang oleh model.

Mari kita lihat perbezaan antara kelas PHP mudah dan model Laravel yang mengakses sifat.

<?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'

Kita dapat melihat bahawa kelas PHP dan Laravel di atas berkelakuan sama.

Walau bagaimanapun, dalam kes Laravel, sifat tidak disimpan seperti PHP biasa, tetapi sebaliknya tertumpu dalam satu sifat yang dipanggil $attributes. Kami masih berjaya mengakses data yang betul, tetapi bagaimana

Ini semua mungkin kerana _getkaedah ajaib. Cuba kita laksanakan contoh mudah sendiri.

<?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'

Kami berjaya! ?

Kita perlu ambil perhatian bahawa kaedah ajaib _get hanya akan dipanggil jika sifat dengan nama yang sepadan tidak ditemui dalam kelas. Ini ialah kaedah sandaran yang dipanggil apabila PHP tidak dapat mencari harta yang diakses dalam kelas. Oleh itu, dalam contoh di bawah, kaedah ajaib _get tidak dipanggil sama sekali.

<?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;

Ada lagi perkara yang berlaku di sebalik tabir. Jika anda ingin mengetahui lebih lanjut tentang bagaimana sebenarnya model Laravel menggunakan __get, anda boleh menyemak kod sumber di bawah.

laravel/rangka kerja

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

Gunakan kaedah ajaib _set apabila harta yang anda cuba tetapkan tidak diisytiharkan dalam kelas. Mari kita lihat semula perbezaan antara kelas dan model PHP biasa dalam Laravel.

<?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

Seperti yang dapat kita lihat, dalam contoh ini kita masih cuba mempengaruhi nilai Bob yang sebenarnya tidak wujud dalam kelas tetapi berada dalam atribut $ attributes. Jom cuba kaedah ajaib __ 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'

Sekarang mari kita mulakan! Kami telah berjaya melaksanakan penggunaan asas kaedah sihir __ get dan __ set dalam Laravel! Mereka boleh melakukannya dengan hanya beberapa baris kod!

Perlu diingat bahawa kaedah sihir ini adalah semudah mungkin tanpa memasukkan terlalu banyak butiran, kerana terdapat lebih daripada itu dan bukan hanya kes penggunaan, dan jika anda ingin tahu tentang cara ia berfungsi, saya menjemput anda Lakukan penerokaan sendiri! (Juga sila hubungi saya di Twitter jika anda mempunyai sebarang pertanyaan)

Begitu juga, jika anda ingin menggali lebih lanjut, paut ke kod sumber di sini

laravel/ rangka kerja

Mari kita beralih kepada perkara terakhir dan paling menarik! ?

<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视频教程

Atas ialah kandungan terperinci Apakah kaedah sihir? Bagaimana untuk menggunakannya dalam Laravel. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:learnku.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam