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 相关文章推荐
一个可以找出源代码中所有中文的工具
Oct 25 PHP
随时给自己贴的图片加文字的php水印
Mar 16 PHP
逐步提升php框架的性能
Jan 10 PHP
PHP中计算字符串相似度的函数代码
Dec 29 PHP
php使用正则过滤js脚本代码实例
May 10 PHP
ThinkPHP3.1新特性之内容解析输出详解
Jun 19 PHP
PHP中单引号与双引号的区别分析
Aug 19 PHP
php提示Warning:mysql_fetch_array() expects的解决方法
Dec 16 PHP
php三种实现多线程类似的方法
Oct 30 PHP
PHP读取XML文件的方法实例总结【DOMDocument及simplexml方法】
Sep 10 PHP
thinkPHP框架乐观锁和悲观锁实例分析
Oct 30 PHP
php swoft框架实例用法
Dec 22 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 DOMElement 操作xml 文档的实现代码
2013/05/10 PHP
thinkphp模板用法和内容输出实例
2014/11/28 PHP
网站防止被刷票的一些思路与方法
2015/01/08 PHP
Laravel 实现数据软删除功能
2019/08/21 PHP
浅谈PHP之ThinkPHP框架使用详解
2020/07/21 PHP
jquery 新手学习常见问题解决方法
2010/04/18 Javascript
禁止你的左键复制实用技巧
2013/01/04 Javascript
jQuery $.extend()用法总结
2014/06/15 Javascript
使用jquery+CSS实现控制打印样式
2014/12/31 Javascript
jQuery幻灯片特效代码分享--鼠标滑过按钮时切换(2)
2020/11/18 Javascript
jquery trigger实现联动的方法
2016/02/29 Javascript
js实现ctrl+v粘贴上传图片(兼容chrome、firefox、ie11)
2016/03/09 Javascript
jQuery实现的省市联动菜单功能示例【测试可用】
2017/01/13 Javascript
js 博客内容进度插件详解
2017/02/19 Javascript
基于JavaScript实现表格滚动分页
2017/11/22 Javascript
JS获取input[file]的值并显示在页面的实现方法
2018/03/09 Javascript
JavaScript偏函数与柯里化实例详解
2019/03/27 Javascript
详解Python的Flask框架中的signals信号机制
2016/06/13 Python
Python实现连接postgresql数据库的方法分析
2017/12/27 Python
安装python3的时候就是输入python3死活没有反应的解决方法
2018/01/24 Python
对Python中DataFrame按照行遍历的方法
2018/04/08 Python
Python使用progressbar模块实现的显示进度条功能
2018/05/31 Python
Python中安装easy_install的方法
2018/11/18 Python
Pycharm 实现下一个文件引用另外一个文件的方法
2019/01/17 Python
Django框架用户注销功能实现方法分析
2019/05/28 Python
Docker部署Python爬虫项目的方法步骤
2020/01/19 Python
python3实现将json对象存入Redis以及数据的导入导出
2020/07/16 Python
Python 排序最长英文单词链(列表中前一个单词末字母是下一个单词的首字母)
2020/12/14 Python
用CSS3来实现社交分享按钮
2014/11/11 HTML / CSS
Easy Spirit官网:美国休闲鞋履中的代表品牌
2019/04/12 全球购物
《理想》教学反思
2014/02/17 职场文书
科研课题实施方案
2014/03/18 职场文书
本科毕业答辩开场白
2015/05/27 职场文书
运动会广播稿20字
2015/08/19 职场文书
MySql重置root密码 --skip-grant-tables
2022/04/11 MySQL
Mybatis-Plus 使用 @TableField 自动填充日期
2022/04/26 Java/Android