了解PHP魔术方法:__toString()、__invoke()和__debugInfo()

最近同事在研究内部开发的组件时,发现了一个__debugInfo()的用法,突然问我,我一时也没有想起这是个什么用法,于是重新阅读下 PHP 手册。

插入一下,先说说 PHP 手册的用法,像这种魔术方法,是无法通过手册中的搜索来找到的,需要通过 URL 访问的方式,例如:

__toString()https://www.php.net/__tostring

__debuginfo()https://www.php.net/__debuginfo

或者你记得它应该是 OOP 中包含的内容,则可以通过 OOP 的首页列表(https://www.php.net/oop)来找到Magic Methods的入口。

同样的,类似于:@...use::???:??=<=> 这种都可以通过在官网后拼接的方式查看对应的手册内容。

什么是魔术方法?

魔术方法是一种特殊的方法,当对对象执行某些操作时会覆盖 PHP 的默认操作。

下列方法名被认为是魔术方法: __construct()__destruct()__call()__callStatic()__get()__set()__isset()__unset()__sleep()__wakeup()__serialize()__unserialize()__toString()__invoke()__set_state()__clone()__debugInfo()

PHP 保留所有以 __ 开头的方法名称。 因此,除非覆盖 PHP 的行为,否则不建议使用此类方法名称。除了 __construct()__destruct()__clone() 之外的所有魔术方法都必须声明为 public

本篇文章主要来看看__toString()__invoke()__debugInfo()这三个魔术方法。

__toString()

public __toString(): string

__toString() 方法用于一个类被当成字符串时应怎样回应。

class TestClass
{
    public function __toString()
    {
        return 'Hello World!';
    }
}

echo (new TestClass());

这个会输出Hello World!

__invoke()

__invoke( ...$values): mixed

当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

class TestClass
{
    public function __invoke($foo, $bar)
    {
        var_dump($foo, $bar);
    }
}
$test = new TestClass();
$test('foo', 'bar');

这个就会打印出foobar

__debugInfo()

__debugInfo(): array

当通过 var_dump() 转储对象,获取应该要显示的属性的时候,该函数就会被调用。

class TestClass
{
    public $param1;
    private $param2;
    protected $param3;

    public function __construct($param1, $param2, $param3)
    {
        $this->param1 = $param1;
        $this->param2 = $param2;
        $this->param3 = $param3;
    }

    public function __debugInfo()
    {
        return [
            'param1' => $this->param1,
            'param2' => $this->param2,
            'param3' => $this->param3,
        ];
    }
}

$test = new TestClass('foo', 'bar', 'baz');
var_dump($test);

如果对象中没有定义该方法,那么将会展示所有的公有、受保护和私有的属性,且会显示对应的属性类型。

object(TestClass)#1 (3) {
  ["param1"]=>
  string(3) "foo"
  ["param2":"TestClass":private]=>
  string(3) "bar"
  ["param3":protected]=>
  string(3) "baz"
}

object(TestClass)#1 (3) {
  ["param1"]=>
  string(3) "foo"
  ["param2"]=>
  string(3) "bar"
  ["param3"]=>
  string(3) "baz"
}

这三个魔术方法,其实都是对于对象的一些操作,通过对 PHP 魔术方法的理解,我们可以更好地掌握对象的行为和调试技术。

深入了解这些方法将有助于提升我们在 PHP 开发中的技能和效率。

本文的示例代码可以通过 https://3v4l.org/NWqMh 查看。

1 条评论

发表评论

*