PHP 魔术方法 - __set()

PHP 魔术方法 - __get() 章节中,我们学习了如何访类实例的不存在的或私有的属性。那么,如果们要对这些属性进行赋值,或者改变它们的值,又要怎么做呢?

我们先来看看默认情况下会不会也报错

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

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

$person = new Person("Yufei", 30);  // 无参数创建实例

$person->name = "Yufei";
$person->sex  = "Male";

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:16
Stack trace:
#0 {main}
  thrown in /Users/yufei/php/demo.php on line 16

看出错的结果在 16 行,也就是 $person->name = "Yufei";

这说明什么 ?

说明 「 给类实例的不存在的或私有的属性赋值,同样会抛出异常 」

同样的,解决办法也很简单,就是给类定义一个 __set() 魔术方法

__set() 魔术方法

魔术方法 __set() 用来给类的实例的不存在的属性或不可访问的属性赋值。

该方法的原型如下

public function __set($property, $value)
{
    // 一些代码
}

该方法有两个参数,第一个参数 $property 是不存在或不可访问的实例的属性,第二个参数 $value 是实际要赋的值。

该方法可以有返回值,也可以没有返回值,完全由开发者自己决定

范例

为了修复一开始的异常,我们为 Person 类定义一个 __set() 方法

<?php

class Person
{
    private $name;
    private $age;

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

    public function __set($property, $value) {
        if ($property=="age")
        {
            if ($value > 150 || $value < 0) {
                return;
            }
        }
        $this->$property = $value;
    }

    public function say(){
        echo "我的名字是: ".$this->name.", 我 ".$this->age." 岁了";
    }
}

$Person=new Person("Yufei", 25); 
$Person->name = "Hero";     // 因为定义了 __set() 方法,所以我们可以给 $name 属性赋值

$person->age = 16;   // 同样的,也可以给 $age 属性赋值
$person->age = 160;  // 因为 160 不符合要求,所以 $age 还是保持原样
$person->say();      // 输出 print:My name is Lili, I'm 16 years old.

运行结果如下

[yufei@localhost php]$ php demo.php 
我的名字是: Hero, 我 16 岁了

使用 __set() 给一个不存在的属性赋值时,该属性的访问级别问题

使用 __set() 给一个不存在的属性赋值时,该属性的访问级别是默认的 public ,请看下面的代码

<?php

class Person
{
    public function __set($property, $value) {
        $this->$property = $value;
    }

}

$person = new Person();
$person->name = 'Yufei';
echo $person->name, "\n";

输出结果如下

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

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

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