美文网首页PHP实战PHP经验分享
PHP反思:__get() /__set()实现类属性

PHP反思:__get() /__set()实现类属性

作者: codefine | 来源:发表于2018-02-08 16:08 被阅读12次

先贴代码

<?php

class InvalidCallException extends \Exception  {}
class UnknownPropertyException extends \Exception {}

/**
 * 定义一个对象类
 * 实现__get()
 * 实现__set()
 * 赋予一个对象属性读写的能力
 */
abstract class Object
{   
    public function __get($key)
    {   
        $method_name = 'get' . $key;
        if (method_exists($this, $method_name)) {
            return call_user_func([$this, $method_name]);
        } else if (method_exists($this, 'set' . $key)) {
            throw new \InvalidCallException("属性是只写的:" . __class__ . '::' . $key);
        } else {
            throw new \UnknownPropertyException("属性不存在:" . __class__ . '::' . $key);
        }
    }

    public function __set($key, $value)
    {   
        $method_name = 'set' . $key;
        if (method_exists($this, $method_name)) {
            return call_user_func([$this, $method_name], $value);
        } else if (method_exists($this, 'get' . $key)) {
            throw new \InvalidCallException("属性是只读的:"  . __class__ . '::' . $key);
        } else {
            throw new \UnknownPropertyException("属性不存在:" . __class__ . '::' . $key);
        }
    }
}


/**
 * Article类
 * title属性,可读写
 * author属性,只读
 * 内部定义私有成员,对外不可见,实现封装
 * 定义getter,setter,设置属性读写,实现封装
 */
class Article extends Object
{

    private $_title;
    private $_author = 'codefine';
    private $_content;

    public function getTitle()
    {
        return $this->_title;
    }

    public function setTitle($title)
    {
        $this->_title = trim($title);
    }

    public function getAuthor()
    {
        return $this->_author;
    }

    public function setContent($value)
    {
        $this->_content = $value;
        var_dump($this->_content);
    }
}

$obj = new Article();

//title 支持读写
$obj->title = '__get __set的使用';
var_dump($obj->title);

//只读
// $obj->author = '修改作者'; //Fatal error: Uncaught InvalidCallException: 属性是只读的:Object::author
var_dump($obj->author);

//只写
$obj->content = '内容属性赋值';
// var_dump($obj->content); // Fatal error: Uncaught InvalidCallException: 属性是只写的:Object::content 

总结

通过代码示例,可以发现,PHP中的类,本身没有设计getter, setter。但提供了__get() / __set()魔术方法,在访问(设置)不存在的类成员的时候,提供回调处理。

通过__get() / __set() 魔术方法,交由程序员自己发挥想象,自行定制实现规则,既可以实现成员的类型限制,也可以实现统一包装,格式化,访问控制等等功能。

相关文章

  • PHP反思:__get() /__set()实现类属性

    先贴代码 总结 通过代码示例,可以发现,PHP中的类,本身没有设计getter, setter。但提供了__get...

  • 面向对象的理解

    封装 语法 类内 private 实现 属性私有,get/set get 获得数据 set 设置数据 alt + ...

  • SubList分页-004-Student类

    Student类 属性+get、set方法 空参/参数构造器 toString方法 实现Serializable接...

  • PHP重载

    PHP中的重载指的是动态的创建属性与方法,是通过魔术方法来实现的。 属性的重载通过__set,__get,__is...

  • JDBC的DAO设计模式

    在javaEE中,java类的属性通过getter和setter来定义,get(或set)方法去除get(set)...

  • Python描述符Descriptor简单使用

    实现了__set__(), __get__()或__delete__()的对象,且描述符属性只能定义在类级别。@p...

  • 【runoob.1】基础语法

    数组用类 Array 实现,并且还有一个 size 属性及 get 和 set 方法,由于使用 [] 重载了 ge...

  • PHP基础 -- 魔术方法

    __construct() 每次实例化一个类都会先调用该方法进行初始化 __get + __set 实现未定义属性...

  • 关联对象函数

    一.分类里面添加属性,不会生成set\get方法实现;以及成员变量;只是声明了set、get函数; 二.给分类间接...

  • Vue - 计算属性、观察者(二)

    computer:计算属性get方法 computer:计算属性get set方法 set:function(ne...

网友评论

    本文标题:PHP反思:__get() /__set()实现类属性

    本文链接:https://www.haomeiwen.com/subject/fnmttftx.html