PHP类中的魔术方法(Magic Method)简明总结


Posted in PHP onJuly 08, 2014

1. __construct()和__destruct()

在实例被 创建/销毁 的时候被调用,都可以传递0个或多个参数。

class A
 {
  function A()
  {
   echo "build A";
  }

  function __destruct()
  {
   echo "destroy A";
  }
 }

 $obj = new A();
 //unset($obj);

Note:The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

关于构造函数,PHP5.3.3开始,一个定义在某个特定的命名空间里的class中以类名命名的方法将不再被认为是构造函数。在无命名空间的类中与原来一样依旧是构造函数。如:

namespace Foo;
class Bar {
  public function Bar() {
    // treated as constructor in PHP 5.3.0-5.3.2
    // treated as regular method as of PHP 5.3.3
  }
}

如果没有namespace Foo; 那么Bar()还将被当作构造函数。另外,如果存在下面的情况:

function __construct()
  {
   echo "construct A";
  }

  function A()
  {
   echo "build A";
  }

  function __destruct()
  {
   echo "destroy A";
  }
 }

即既包含__construct()又包含与类名同名的函数,那么将只调用__construct()。

2. __call()和__callStatic()

当尝试调用一个不存在的方法时调用该方法。两个参数,一个是方法名,一个是被调用方法的参数数组。

class MethodTest
{
  public function __call($name, $arguments)
  {
    // Note: value of $name is case sensitive.
    echo "Calling object method '$name' "
       . implode(' ', $arguments). "<br>";
  }

  public static function __callStatic($name, $arguments)
  {
    // Note: value of $name is case sensitive.
    echo "Calling static method '$name' "
       . implode(' ', $arguments). "<br>";
  }
}

$obj = new MethodTest;
$obj->runTest('in','object','context');
MethodTest::runTest('in','static','context');

其中,$arguments作为一个array传入。运行结果:

Calling object method 'runTest' in object context
Calling static method 'runTest' in static context

还要注意函数的作用域protected和private:

class TestMagicCallMethod {
  public function foo()
  {
    echo __METHOD__.PHP_EOL."<br>";
  }

  public function __call($method, $args)
  {
    echo __METHOD__.PHP_EOL."<br>";
    if(method_exists($this, $method))
    {
      $this->$method();
    }
  }
  
  protected function bar()
  {
    echo __METHOD__.PHP_EOL."<br>";
  }

  private function baz()
  {
    echo __METHOD__.PHP_EOL."<br>";
  }
}

$test  =  new TestMagicCallMethod();
$test->foo();
/**
 * Outputs:
 * TestMagicCallMethod::foo
 */

$test->bar();
/**
 * Outputs:
 * TestMagicCallMethod::__call
 * TestMagicCallMethod::bar
 */

$test->baz();
/**
 * Outputs:
 * TestMagicCallMethod::__call
 * TestMagicCallMethod::baz
 */

3.__get()和__set()

当试图读取一个对象并不存在的属性的时候被调用。

Note:我们可以用这个函数实现类似java中反射的各种操作。

class Test
{
  public function __get($key)
  {
   echo $key . " not exists";
  }
  public function __set($key,$value)
  {
   echo $key . " = ".$value;
  }
}

$t = new Test();
echo $t->name."<br>";
$t->name = "abc";

输出:
name not exists
name = abc

4. __toString()

 这个方法类似于java的toString()方法,当我们直接打印对象的时候回调用这个函数,函数必须返回一个string。

class Test
{
  private $name = "abc";
  private $age = 12;

  public function __toString()
  {
    return "name : $this->name, age : $this->age";
  }
}

$t = new Test();
echo $t;

输出:

name : abc, age : 12

PHP 相关文章推荐
php中session使用示例
Mar 29 PHP
PHP实现显示照片exif信息的方法
Jul 11 PHP
PHP 接入支付宝即时到账功能
Sep 18 PHP
ThinkPHP实现简单登陆功能
Apr 28 PHP
PHP基于IMAP收取邮件的方法示例
Aug 07 PHP
PHP实现链式操作的三种方法详解
Nov 16 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
Feb 23 PHP
PHP7基于curl实现的上传图片功能
May 11 PHP
PHP __call()方法实现委托示例
May 20 PHP
windows 2008r2+php5.6.28环境搭建详细过程
Jun 18 PHP
php设计模式之策略模式实例分析【星际争霸游戏案例】
Mar 26 PHP
php实现对短信验证码发送次数的限制实例讲解
Mar 04 PHP
PHP的魔术常量__METHOD__简介
Jul 08 #PHP
PHP中的插件机制原理和实例
Jul 08 #PHP
phpmailer在服务器上不能正常发送邮件的解决办法
Jul 08 #PHP
php去掉URL网址中带有PHPSESSID的配置方法
Jul 08 #PHP
PHP大批量插入数据库的3种方法和速度对比
Jul 08 #PHP
php发送get、post请求的6种方法简明总结
Jul 08 #PHP
PHP中对各种加密算法、Hash算法的速度测试对比代码
Jul 08 #PHP
You might like
第五章 php数组操作
2011/12/30 PHP
浅析PHP递归函数返回值使用方法
2013/02/18 PHP
php将mysql数据库整库导出生成sql文件的具体实现
2014/01/08 PHP
PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式
2014/06/12 PHP
浅谈PHP array_search 和 in_array 函数效率问题
2019/10/15 PHP
定义select的边框颜色
2008/04/28 Javascript
判断脚本加载是否完成的方法
2009/05/26 Javascript
批量实现面向对象的实例代码
2013/07/01 Javascript
js 定时器setTimeout无法调用局部变量的解决办法
2013/11/28 Javascript
在JS中解析HTML字符串示例代码
2014/04/16 Javascript
jquery easyui 结合jsp简单展现table数据示例
2014/04/18 Javascript
jQuery自适应轮播图插件Swiper用法示例
2016/08/24 Javascript
vue如何引用其他组件(css和js)
2017/04/13 Javascript
简单实现js上传文件功能
2017/08/21 Javascript
AngularJS中下拉框的基本用法示例
2017/10/11 Javascript
Nginx 配置多站点vhost 的方法
2018/01/07 Javascript
VUE2.0中Jsonp的使用方法
2018/05/22 Javascript
webpack-url-loader 解决项目中图片打包路径问题
2019/02/15 Javascript
17道题让你彻底理解JS中的类型转换
2019/08/08 Javascript
[01:33:07]VGJ.T vs Newbee Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
numpy的文件存储.npy .npz 文件详解
2018/07/09 Python
python正则表达式匹配[]中间为任意字符的实例
2018/12/25 Python
在python下读取并展示raw格式的图片实例
2019/01/24 Python
windows下numpy下载与安装图文教程
2019/04/02 Python
python实现基于朴素贝叶斯的垃圾分类算法
2019/07/09 Python
深入浅析Python 中的sklearn模型选择
2019/10/12 Python
Python 过滤错误log并导出的实例
2019/12/26 Python
一家外企的面试题目(C/C++面试题,C语言面试题)
2014/03/24 面试题
智能电子应届生求职信
2013/11/10 职场文书
超市客服工作职责
2014/06/11 职场文书
社区党员志愿服务活动方案
2014/08/18 职场文书
教师党员个人剖析材料
2014/09/29 职场文书
大学生档案自我鉴定(2篇)
2014/10/14 职场文书
特岗教师个人总结
2015/02/10 职场文书
贷款工资证明范本
2015/06/12 职场文书
某某店铺的开业庆典主持词范本
2019/11/25 职场文书