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 相关文章推荐
在Windows版的PHP中使用ADO
Oct 09 PHP
使用PHP的日期与时间函数技巧
Apr 24 PHP
php session 检测和注销
Mar 16 PHP
通过PHP CLI实现简单的数据库实时监控调度
Jul 01 PHP
php实现memcache缓存示例讲解
Dec 04 PHP
基于php和mysql的简单的dao类实现crud操作功能
Jan 27 PHP
Thinkphp中Create方法深入探究
Jun 16 PHP
对PHP新手的一些建议(PHP学习经验总结)
Aug 20 PHP
PHP计算当前坐标3公里内4个角落的最大最小经纬度实例
Feb 26 PHP
php微信公众号开发(4)php实现自定义关键字回复
Dec 15 PHP
PHP实现的策略模式简单示例
Aug 25 PHP
PHP面向对象多态性实现方法简单示例
Sep 27 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判断终端是手机还是电脑访问网站的思路及代码
2013/04/24 PHP
php实现倒计时效果
2015/12/19 PHP
PHP的邮件群发系统phplist配置方法详细总结
2016/03/30 PHP
php使用number_format函数截取小数的方法分析
2016/05/27 PHP
ThinkPHP3.2.3实现分页的方法详解
2016/06/03 PHP
yii框架搜索分页modle写法
2016/12/19 PHP
ie和firefox不兼容的解决方法集合
2009/04/28 Javascript
jQuery中的常用事件总结
2009/12/27 Javascript
firefox firebug中文入门教程 脚本之家新年特别版
2010/01/02 Javascript
JS常见问题整理(持续更新)
2013/08/06 Javascript
使用insertAfter()方法在现有元素后添加一个新元素
2014/05/28 Javascript
javascript 回调函数详解
2014/11/11 Javascript
浅谈node.js中async异步编程
2015/10/22 Javascript
jQuery链式操作实例分析
2015/11/16 Javascript
使用jQuery mobile库检测url绝对地址和相对地址的方法
2015/12/04 Javascript
基于javascript实现九宫格大转盘效果
2020/05/28 Javascript
开启BootStrap学习之旅
2016/05/04 Javascript
js将table的每个td的内容自动赋值给其title属性的方法
2016/10/13 Javascript
AngularJS报错$apply already in progress的解决方法分析
2017/01/30 Javascript
二维码图片生成器QRCode.js简单介绍
2017/08/18 Javascript
swiper动态改变滑动内容的实现方法
2018/01/17 Javascript
基于vue v-for 循环复选框-默认勾选第一个的实现方法
2018/03/03 Javascript
es6中Promise 对象基本功能与用法实例分析
2020/02/23 Javascript
mapboxgl区划标签避让不遮盖实现的代码详解
2020/07/01 Javascript
vue 实现一个简单的全局调用弹窗案例
2020/09/10 Javascript
详解vue中在父组件点击按钮触发子组件的事件
2020/11/13 Javascript
Python使用百度API上传文件到百度网盘代码分享
2014/11/08 Python
Python实现识别手写数字 Python图片读入与处理
2020/03/23 Python
详解Python是如何实现issubclass的
2019/07/24 Python
Python产生一个数值范围内的不重复的随机数的实现方法
2019/08/21 Python
Python自动生成代码 使用tkinter图形化操作并生成代码框架
2019/09/18 Python
Python实现画图软件功能方法详解
2020/07/28 Python
市场调查策划方案
2014/06/10 职场文书
工作检讨书范文
2015/01/23 职场文书
浅谈由position属性引申的css进阶讨论
2021/05/25 HTML / CSS
微软Win11什么功能最惊艳? Windows11新功能特性汇总
2021/11/21 数码科技