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

先来看一段代码:

class Article{
    //私有成员属性
    private $title = '标题';

    //受保护的成员属性
    protected $author = '作者';

    //公有成员属性
    public $introduce = '简介';
}

$article = new Article();
var_dump($article -> title);
var_dump($article -> author);
var_dump($article -> introduce);

对象直接访问类中的private和protected成员属性时,会报一个Fatal error的错误,提示“Cannot access private property”或者“Cannot access protected property”。

1、魔术方法__get()

如果对象要直接访问类中的private和protected成员属性呢? PHP给我们提供了一个魔术方法“__get()”,用于获取private和protected成员属性。

class Article{

    //私有成员属性
    private $title = '标题';

    //受保护的成员属性
    protected $author = '作者';

    //公有成员属性
    public $introduce = '简介';

    //获取private和protected成员属性
    public function __get($name){·
        if(isset($this -> $name)) {
            return $this->$name;
        }
        return false;
    }

}

$article = new Article();
var_dump($article -> title);
var_dump($article -> author);
var_dump($article -> introduce);

执行结果如下:

string(6) "标题" string(6) "作者" string(6) "简介"

可以看出,__get()魔术方法并不需要我们显示的去调用;类本身会隐式的去调用此方法。而且,private和protected成员属性都可以通过此魔术方法获取相应的数据。

2、魔术方法__set()

如果对象要直接对类中的private和protected成员属性赋值呢? PHP给我们提供了一个魔术方法“__set()”,用于对private和protected成员属性进行赋值操作。

class Article{

    //私有成员属性
    private $title = '标题';

    //受保护的成员属性
    protected $author = '作者';

    //公有成员属性
    public $introduce = '简介';

    //获取private和protected成员属性
    public function __get($name){
        if(isset($this -> $name)) {
            return $this->$name;
        }
        return false;
    }

    //设置private和protected成员属性
    public function __set($name, $value){
        if(isset($this -> $name)){
            $this -> $name = $value;
        }
    }
}

$article = new Article();
$article -> title = '文章标题';
$article -> author = '文章作者';
$article -> introduce = '文章简介';

var_dump($article -> title);
var_dump($article -> author);
var_dump($article -> introduce);

执行结果如下:

string(12) "文章标题" string(12) "文章作者" string(12) "文章简介"

__set()魔术方法也不需要显示的调用;类本身也会隐式的去调用此方法。而且,private和protected成员属性都可以通过此魔术方法去设置相应的值。特别注意一点,所有的魔术方法都必须声明为public,各位可以去实现一遍代码,测试便知。

其实get()和set()这两个魔术方法都是PHP“重载(overload)”特性的体现。PHP中的"重载"与其它绝大多数面向对象语言不同。传统的"重载"是用于提供多个同名的类方法,但各方法的参数类型和个数不同。而PHP中的“重载”是指动态地“创建”类属性和方法,即通过魔术方法(magic methods)来实现。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏微信公众号:Java团长

Java虚拟机工作原理

首先我想从宏观上介绍一下Java虚拟机的工作原理。从最初的我们编写的Java源文件(.java文件)是如何一步步执行的,如下图所示,首先Java源文件经过前端编...

752
来自专栏Play & Scala 技术分享

Play Scala 2.5.x - Play JSON开发指南

2815
来自专栏技术墨客

Spring核心——数据校验

在Java数据校验详解中详细介绍了Java数据校验相关的功能(简称Bean Validation,涵盖JSR-303、JSR-349、JSR-380),本文将在...

1762
来自专栏你不就像风一样

抛弃配置后的Spring终极教程

对于Spring,核心就是IOC容器,这个容器说白了就是把你放在里面的对象(Bean)进行统一管理,你不用考虑对象如何创建如何销毁,从这方面来说,所谓的控制反转...

842
来自专栏技术墨客

Spring核心——数据校验

在Java数据校验详解中详细介绍了Java数据校验相关的功能(简称Bean Validation,涵盖JSR-303、JSR-349、JSR-380),本文将在...

391
来自专栏小灰灰

SPI框架实现之旅四:使用测试

SPI框架实现之旅四:使用测试 前面三篇主要是介绍如何设计的,如何实现的,这一篇,则主要集中在如何使用。实现得再好,如果不好用,也白搭 本篇介绍几个简单的使用...

1878
来自专栏青枫的专栏

java基础学习_IO流01_异常、File类_day19总结

491
来自专栏精讲JAVA

Java异常面试问题

异常是在程序执行期间可能发生的错误事件,并且会中断它的正常流程。异常可能来自不同类型的情况,例如用户输入的错误数据,硬件故障,网络连接故障等。

663
来自专栏Java Web

Spring(3)——装配 Spring Bean 详解

装配 Bean 的概述 前面已经介绍了 Spring IoC 的理念和设计,这一篇文章将介绍的是如何将自己开发的 Bean 装配到 Spring IoC 容器中...

3634
来自专栏每日一篇技术文章

Swift3.0 - 扩展

b.如果想要在定义协议的时候,不指定变量名称,在实现协议的时候,再去设定变量类型,应该怎么写?

543

扫码关注云+社区