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 相关文章推荐
GBK的页面输出JSON格式的php函数
Feb 16 PHP
php中在PDO中使用事务(Transaction)
May 14 PHP
PHP下通过exec获得计算机的唯一标识[CPU,网卡 MAC地址]
Jun 09 PHP
Linux环境下搭建php开发环境的操作步骤
Jun 17 PHP
PHP中对于浮点型的数据需要用不同的方法解决
Mar 11 PHP
调试PHP程序的多种方法介绍
Nov 06 PHP
PHP数组和explode函数示例总结
May 08 PHP
yii的入口文件index.php中为什么会有这两句
Aug 04 PHP
PHP简单实现上一页下一页功能示例
Sep 14 PHP
在 Laravel 中 “规范” 的开发短信验证码发送功能
Oct 26 PHP
PHP保存Base64图片base64_decode的问题整理
Nov 04 PHP
PHP7 其他语言层面的修改
Mar 09 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
56.com视频采集接口程序(PHP)
2007/09/22 PHP
php学习笔记 php中面向对象三大特性之一[封装性]的应用
2011/06/13 PHP
PHP实现将base64编码字符串转换成图片示例
2018/06/22 PHP
聊聊 PHP 8 新特性 Attributes
2020/08/19 PHP
Javascript下IE与Firefox下的差异兼容写法总结
2010/06/18 Javascript
Jquery 获取checkbox的checked问题
2011/11/16 Javascript
jQuery 快速结束当前正在执行的动画
2013/11/20 Javascript
关闭时刷新父窗口两种方法
2014/05/07 Javascript
在linux中使用包管理器安装node.js
2015/03/13 Javascript
jQuery在线选座位插件seat-charts特效代码分享
2015/08/27 Javascript
jQuery实现带渐显效果的人物多级关系图代码
2015/10/16 Javascript
jQuery实现选项卡切换效果简单演示
2015/12/09 Javascript
JS中innerHTML和pasteHTML的区别实例分析
2016/06/22 Javascript
js捕捉键盘事件和按键键值的方法
2016/10/10 Javascript
bootstrap使用validate实现简单校验功能
2016/12/02 Javascript
jquery hover 不停闪动问题的解决方法(亦为stop()的使用)
2017/02/10 Javascript
关于vue-router的beforeEach无限循环的问题解决
2017/09/09 Javascript
angularJS实现动态添加,删除div方法
2018/02/27 Javascript
通过vue提供的keep-alive减少对服务器的请求次数
2018/04/01 Javascript
mock.js模拟前后台交互
2019/07/25 Javascript
Vue实现简单计算器
2021/01/20 Vue.js
Python中条件选择和循环语句使用方法介绍
2013/03/13 Python
在 Django/Flask 开发服务器上使用 HTTPS
2014/07/03 Python
python运行其他程序的实现方法
2017/07/14 Python
Python基于opencv调用摄像头获取个人图片的实现方法
2019/02/21 Python
StubHub墨西哥:购买和出售您的门票
2016/09/17 全球购物
Habitat家居英国官方网站:沙发、家具、照明、厨房和户外
2019/12/12 全球购物
英国排名第一的冲浪店:Ann’s Cottage
2020/06/21 全球购物
《特殊的葬礼》教学反思
2014/04/27 职场文书
授权委托书(公民个人适用)
2014/09/19 职场文书
2015年推广普通话演讲稿
2015/03/20 职场文书
物业工程部主管岗位职责
2015/04/16 职场文书
2015教师个人年度工作总结
2015/10/23 职场文书
Mysql MVCC机制原理详解
2021/04/20 MySQL
浅析JavaScript中的变量提升
2022/06/01 Javascript
Zabbix对Kafka topic积压数据监控的问题(bug优化)
2022/07/07 Servers