PHP 魔术方法 __get() 和 __set()

在 php 的面向对象编程中,当一个成员属性被定义为 private 或 protected 时,如果我们试图在外面直接调用它或者给属性赋值都会出现“不能访问某个私有属性或受保护属性”的错误。面对这样的需求,PHP 提供了 __get() 和 __set() 的魔术方法。其中 __get() 可以访问非公有属性,__set() 可以给非公有属性赋值。

1、__get()

方法必须有一个参数

public function __get($name) // 必有一个参数

案例

class Person
{
    private $name;
    private $age;

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

    /**
     * 在类中添加__get()方法,在直接获取非公有属性时自动调用一次,以属性名作为参数传入并处理
     * @param $name 访问的属性名
     *
     * @return int
     */
    public function __get($name)
    {
        if ($name == "age") {
            if ($this->age > 30) {
                return $this->age - 10;
            } else {
                return $this->$name;
            }
        } else {
            return $this->$name;
        }
    }
}
$person = new Person("kevin", 60);   // 通过Person类实例化的对象,并通过构造方法为属性赋初值
echo "姓名:" . $person->name . "\r\n";   // kevin, 直接访问私有属性name,自动调用了__get()方法可以间接获取
echo "年龄:" . $person->age . "\r\n";    // 50, 自动调用了__get()方法,根据对象本身的情况会返回不同的值
echo "\r\n";

2、__set()

方法必须有两个参数,参数一:属性名,参数二:属性值

public function __set($name, $value)

案例

class Person
{
    private $name;
    private $age;

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

    /**
     * 在类中添加 __get()方法,在直接获取非公有属性时自动调用一次,以属性名作为参数传入并处理
     * @param $propertyName
     *
     * @return int
     */
    public function __get($propertyName)
    {
        if ($propertyName == "age") {
            if ($this->age > 30) {
                return $this->age - 10;
            } else {
                return $this->$propertyName;
            }
        } else {
            return $this->$propertyName;
        }
    }

    /**
     * 在类中添加 __set()方法,给对象的非公有属性赋值
     * @param $name 要赋值的属性
     * @param $value
     */
    public function __set($name, $value)
    {
        $this->$name = $value;
    }
}
$person = new Person("kevin", 60);   // 通过Person类实例化的对象,并通过构造方法为属性赋初值
$person->name = 'loedan';
$person->age = 20;
echo "姓名:" . $person->name . "\r\n";   // loedan, 通过 __set() 给属性赋值
echo "年龄:" . $person->age . "\r\n";    // 20, 通过 __set() 给属性赋值
echo "\r\n";
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,794评论 1 32
  • 类是一个重要的C#编程概念,它在一个单元内定义了表示和行为。类提供了面向对象编程和面向组件编程所需的语言支持,是创...
    CarlDonitz阅读 4,375评论 0 2
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 7,881评论 2 9
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 11,711评论 0 17
  • 一、Apache、PHP、MySQL安装 1、Apache的安装 1.1 安装: 在dos界面进入安装包的bin目...
    像素规划师阅读 4,976评论 3 4