PHP 魔术方法 - __get()

当我们试图访问 PHP 对象中的不存在的属性或者私有的属性时,程序会抛出异常并且停止执行,例如下面的代码

<?php
class Person
{
    private $name;
    private $age;

    function __construct($name="", $age=1)
    {
        $this->name = $name;
        $this->age = $age;
    }
}

$person = new Person("Yufei", 30);  // 使用参数 "Yufei" 和 30 初始化一个对象
echo "Name:" . $person->name . "\n";
echo "Sex:  " . $person->sex . "\n"; // 因为程序终止执行,所以这一条语句不会执行

运行结果如下

[yufei@localhost php]$ php demo.php

Fatal error: Uncaught Error: Cannot access private property Person::$name in /Users/yufei/php/demo.php:15
Stack trace:
#0 {main}
  thrown in /Users/yufei/php/demo.php on line 15

出现这种异常是我们不想看到的,一种解决办法就是给私有的变量定义一个公开的访问方法。但如果是一个不存在的变量,就没办法定义一个公开的方法了。

没有其它办法了吗?

答案是显而易见的,因为我们的标题就是 __get() 魔术方法啊

__get() 魔术方法

当一个类定义了一个 __get() 魔术方法后,我们就可以获取该类的实例的私有属性或不存在的属性而不犯错,这里所说的获取,是指获取其值。

该方法的原型如下

 public mixed function __get( string $propertyName)
 {
    // 一些代码
 }

该方法只有一个参数,就是要获取的属性名称,且该函数可以返回任意数据类型,且必须有返回值。

范例

下面的方法,我们为 Person 定义了魔术方法 __get(),从而解决上面出现的异常问题

<?php
class Person
{
    private $name;
    private $age;

    function __construct($name="", $age=1)
    {
        $this->name = $name;
        $this->age = $age;
    }

    public function __get($propertyName)
    {   
        if ($propertyName == "age") {
            if ($this->age > 30) {
                return $this->age - 10;
            } else {
                return $this->$propertyName;
            }
        } else {
            return $this->$propertyName;
        }
    }
}

$person = new Person("Yufei", 30);   // 使用参数 "Yufei" 和 30 初始化一个对象

echo "Name:" . $person->name . "\n";   // 当访问不可访问的属性时,会自动调用 __get() 方法
echo "Age:" .  $person->age . "\n";    // 返回不一样的值
echo "Sex: " .  $person->sex . "\n";    // 当访问不存在的属性时

运行结果如下

[yufei@localhost php]$ php demo.php
Name:Yufei
Age:30
Sex: 

可以看到,当我们定义了 __get() 方法,即使属性不存在,也会返回一个 NULL 值

类的实例内部访问不存在的属性返回 NULL

这里有一个知识点,就是类的实例内部访问一个不能存在的属性,会返回 NULL 值,可以看如下的代码

<?php
class Person
{
    private $name;
    private $age;

    function say()
    {
        var_dump($this->sex);
    }
}

$person = new Person("Yufei", 30);   // 使用参数 "Yufei" 和 30 初始化一个对象
$person->say();

运行结果如下

[yufei@localhost php]$ php demo.php
NULL
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.