PHP中的常见魔术方法功能作用及用法实例(2)

该魔术方法最常用的地方就是通过创建一个“只读”的属性来扩展访问控制。在上面的Battery类中,有一个私有属性$charge,我们可以通过__get()魔术方法将该属性扩展为在类外部可读但不能修改。代码如下:

复制代码 代码如下:


class Battery {
    private $charge = 0;
 
    public function  __get($name) {
        if(isset($this->$name)) {
            return $this->$name;
        }
        return null;
    }
}

__set()

__set()魔术方法在我们尝试修改一个不可访问的属性时会被调用,它接收两个参数,一个表示属性的名字,一个表示属性的值。示例代码如下:

复制代码 代码如下:


class Device {
    public function  __set($name, $value) {
        // use the property name as the array key
        $this->data[$name] = $value;
    }
}

__isset()

__isset()魔术方法在对一个不可访问的属性调用isset()方法时会被调用,它接收一个参数,表示属性的名字。它应该返回一个布尔值,用来表示该属性是否存在。代码如下:

复制代码 代码如下:


class Device {
    public function  __isset($name) {
        return array_key_exists($name, $this->data);
    }
}

__unset()

__unset()魔术方法在调用unset()函数销毁一个不能访问的属性时会被调用,它接收一个参数,表述属性的名字。

对象转换为字符串

有时候我们需要将对象以字符串的形式表现出来。如果我们直接打印一个对象,那么程序将会输出一个错误信息:PHP Catchable fatal error: Object of class Device could not be converted to string

__toString()

__toString()在我们将对象当作字符串一样使用时会被调用,它不接收任何参数。该方法允许我们定义对象的表现形式。代码如下:

复制代码 代码如下:


class Device {
    public function  __toString() {
       $connected = (isset($this->connection)) ? 'connected' : 'disconnected';
       $count = count($this->data);
       return $this->name . ' is ' . $connected . ' with ' . $count . ' items in memory' . PHP_EOL;
    }
    ...
}

__set_state()(PHP 5.1)

静态魔术方法__set_state(),在我们使用var_export()函数输出对象时会调用该方法。var_export()函数用来将PHP变量转换为PHP代码,它接收一个包含对象属性值的关联数组作为参数。示例代码如下:

复制代码 代码如下:


class Battery {
    //...
    public static function  __set_state(array $array) {
        $obj = new self();
        $obj->setCharge($array['charge']);
        return $obj;
    }
    //...
}

克隆对象

默认的,对象都是按引用传值的。因此,在将一个对象赋值给另一个变量时,只是创建了指向该对象的一个引用,并没有复制该对象。为了实现真正得复制一个对象,我们需要使用clone关键字。
这种“按引用传递”的策略同样适用于包含在对象内部的对象。即使我们克隆了一个对象,在对象内部的任何对象都不会被克隆,因此最终的结果是两个对象共享了同一个内部对象。示例代码如下:

复制代码 代码如下:


$device = new Device(new Battery(), 'iMagic');
$device2 = clone $device;
 
$device->battery->setCharge(65);
echo $device2->battery->charge;
// 65

__clone()

__clone()魔术方法__clone()可以解决上面的问题。当对一个对象使用clone关键字时,该魔术方法会被调用。在这个魔术方法里,我们可以实现任何子对象的克隆,代码如下:

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/c002b85913bad5b8b59aee24c8bf5a73.html