0

0

php的魔术方法__get(),__set(),__call(),__callStatic()以及static用法详解

伊谢尔伦

伊谢尔伦

发布时间:2017-07-03 11:43:44

|

3603人浏览过

|

来源于php中文网

原创

php5之后实现了一些魔术方法还是比较有意思的,之前一直用面向过程的编程方法,对oop研究的比较少,最近在看oop的东西,还是比较有意思的。

魔术方法这些东西,感觉很大一部分就是为了偷懒用的,记得最早写php的时候,那时候做博客,用的是国外的一个叫lifetype的开源框架,那时候还是php4.3,但是那个框架里全部实现了对象,所有的数据都被封装到对象中。

于是当从db里select出来一堆东西之后,还要逐个循环封装成对象,每一个字段也要实现getField()和getField()方法,写起来还真有点麻烦,感觉就是在做重复性的工作。

那么get(),set(),call(),callStatic()这几个魔术方法的诞生,就完全解决了这个问题。

get()和set()是针对类中属性的而call()是针对方法的,callStatic() 是针对静态类的方法。

立即学习PHP免费学习笔记(深入)”;

一、get()和set()魔术方法:

当实例化一个对象后,调用类中不存在或者没有权限访问的属性的时候,php会默认调用get()方法,这样做,不仅可以少些很多代码,让结构更清晰,而且也提供了一条外部访问类的私有成员的一种方法。

比如:

name;

上面的代码,如果我们运行,会报一个错误:PHP Fatal error:  Cannot access private property testGet::$name in /Library/WebServer/Documents/workspace/learn/call/a.php on line 7

但是我们修改一下,通过get()方法就可以访问

$property) ) 
      return $this->$property;
    else
      return NULL;
  }
}
$test = new testGet();
echo $test->name . PHP_EOL;

代码改成这样之后我们再访问就没有问题。 

注意:如果把属性定义成是static的,那么通过get()访问也会报错。原因是static的成员,是属于类本身的,不因为实例化而改变,可以自己测试。

利用set()方法,可以禁止动态创建类属性,这样可以很好的避免给后来开发者,或者程序维护者带来不必要的麻烦。

funciton set($property) {

//$property接收的是属性的名字

}

是实话,oop这个东西的设计,会掺杂很多设计者自己的思想,如果没有文档,后来者去读代码还是很费劲的,当然和后来者的水平也有很大关系。

下面是一个get和set配合使用的例子:

Playground AI
Playground AI

AI图片生成和修图

下载
$property) ) 
      return $this->$property;
    else
      return NULL;
  }
  
  public function set($property, $value) {
    if ( isset($this->$property) )
      $this->$property = $value;
    else
      return NULL;
  }
}
$test = new testGet();
$test->name = 'my test name';
echo $test->name . PHP_EOL;

function set($property, $value) {

//$property接收的属性的名字

//$value接收的是属性的值

}

二、call()和callStatic()方法:

当对象调用类中一个不存在或者没有权限访问的方法的时候,就会自动调用call()方法。

记得以前有个同事问我,tp框架中为什么有很多底层的方法没有,但是在上层还能调用,其实就是call()这个方法在起作用。

如果你不知道这个方法,那么肯定会很疑惑,而且问题也不好定位。

objData[strtolower($matches[1])];
            $field = preg_match('/^set(\w+)/', $name, $matches);
            if ( $field && $matches[1] ) { 
                return $this->objData[strtolower($matches[1])] = $args[0];
            }   
        }   
}
class User extends Obj
{
        
}
$user = new User();
$user->setName('test');
echo $user->getName();

User类什么都没干,但是通过继承类的call()方法,把所有的事都做了(getName和setName)。

function call($methodName, $args) {

//$methodName调用的方法名

//$args传递的参数数组

}

和call()对应的是callStatic()方法,是位静态类的静态方法服务的。

例子:

三、延迟静态绑定:static这个对象

相关专题

更多
云朵浏览器入口合集
云朵浏览器入口合集

本专题整合了云朵浏览器入口合集,阅读专题下面的文章了解更多详细地址。

0

2026.01.20

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

20

2026.01.20

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

62

2026.01.19

java用途介绍
java用途介绍

本专题整合了java用途功能相关介绍,阅读专题下面的文章了解更多详细内容。

87

2026.01.19

java输出数组相关教程
java输出数组相关教程

本专题整合了java输出数组相关教程,阅读专题下面的文章了解更多详细内容。

39

2026.01.19

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

10

2026.01.19

xml格式相关教程
xml格式相关教程

本专题整合了xml格式相关教程汇总,阅读专题下面的文章了解更多详细内容。

13

2026.01.19

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

19

2026.01.19

微信聊天记录删除恢复导出教程汇总
微信聊天记录删除恢复导出教程汇总

本专题整合了微信聊天记录相关教程大全,阅读专题下面的文章了解更多详细内容。

160

2026.01.18

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.9万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 8.7万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号