PHP魔术方法的使用示例


Posted in PHP onJune 23, 2015

① __get/__set:将对象的属性进行接管

当访问一个不存在的对象属性时:

index.php

<?php

define('BASEDIR',__DIR__); //定义根目录常量

include BASEDIR.'/Common/Loader.php';

spl_autoload_register('\\Common\\Loader::autoload');
$obj = new \Common\Object(); 
//在php中访问一个不存在的对象属性时

echo $obj->title;

会抛出一个错误:Notice: Undefined property: Common\Object::$title in D:\practise\php\design\psr0\index.php on line 9

当在Common/Object.php 中添加 __set 和 __get 方法后

Object.php

<?php

namespace Common;
class Object{

    function __set($key,$value){

    }

    

    function __get($key){

    }

}

再执行 index.php,不会再报错。

再次修改 Common/Object.php

<?php

namespace Common;
class Object{

    protected $array = array();

    

    function __set($key,$value){

        var_dump(__METHOD__);

        $this->array[$key] = $value;

    }

    

    function __get($key){

        var_dump(__METHOD__);

        return $this->array[$key];

    }

}

index.php
<?php

define('BASEDIR',__DIR__); //定义根目录常量

include BASEDIR.'/Common/Loader.php';

spl_autoload_register('\\Common\\Loader::autoload');
$obj = new \Common\Object(); 
$obj->title = 'hello';

echo $obj->title;

执行 index.php,页面输出:

string 'Common\Object::__set' (length=20)

string 'Common\Object::__get' (length=20)

hello

② __call/__callStatic:控制 PHP 对象方法的调用(__callStatic 用来控制类的静态方法)

当执行一个不存在的php方法时

index.php:

<?php

define('BASEDIR',__DIR__); //定义根目录常量

include BASEDIR.'/Common/Loader.php';

spl_autoload_register('\\Common\\Loader::autoload');
$obj = new \Common\Object(); 
//当执行一个不存在的php方法时

$obj->test('hello',123);

执行 index.php 会报一个致命错误:Fatal error: Call to undefined method Common\Object::test() in D:\practise\php\design\psr0\index.php on line 9

如果在 Common/Object 中定义一个__call 方法,则会在方法不存在时自动回调:

<?php

namespace Common;
class Object{    

    function __call($func, $param){ //$func 方法名 $param 参数

        var_dump($func, $param);

        return "magic function\n"; //返回一个字符串作为返回值

    }

}

index.php

<?php

define('BASEDIR',__DIR__); //定义根目录常量

include BASEDIR.'/Common/Loader.php';

spl_autoload_register('\\Common\\Loader::autoload');
$obj = new \Common\Object(); 
//当执行一个不存在的php方法时

echo $obj->test('hello',123);

页面输出:

string 'test' (length=4)

array

  0 => string 'hello' (length=5)

  1 => int 123

magic function

当调用一个不存在的静态方法时

Common/Object.php

<?php

namespace Common;
class Object{

    static function __callStatic($name, $arguments) {

        var_dump($name, $arguments);

        return "magic function\n"; //返回一个字符串作为返回值        

    }

}

注意:__callStatic 方法也要声明成静态方法

index.php

<?php

define('BASEDIR',__DIR__); //定义根目录常量

include BASEDIR.'/Common/Loader.php';

spl_autoload_register('\\Common\\Loader::autoload');
//执行一个不存在的静态方法

echo Common\Object::test("hello",1234);

执行 index.php ,页面输出:

string 'test' (length=4)

array

  0 => string 'hello' (length=5)

  1 => int 1234

magic function

③ __toString:将一个 PHP 对象转换成一个字符串

index.php

<?php

define('BASEDIR',__DIR__); //定义根目录常量

include BASEDIR.'/Common/Loader.php';

spl_autoload_register('\\Common\\Loader::autoload');
$obj = new \Common\Object();
echo $obj;

此时会报错: Catchable fatal error: Object of class Common\Object could not be converted to string in D:\practise\php\design\psr0\index.php on line 8

在 Object.php 中添加 __toString 方法

<?php

namespace Common;
class Object{

    function __toString() {

        return __CLASS__;

    }

}

④ __invoke:将一个 PHP 对象当成一个函数来执行时,会回调此魔术方法

index.php

<?php

define('BASEDIR',__DIR__); //定义根目录常量

include BASEDIR.'/Common/Loader.php';

spl_autoload_register('\\Common\\Loader::autoload');
$obj = new \Common\Object();
echo $obj("test");

Object.php
<?php

namespace Common;
class Object{

    function __invoke($param) {

        var_dump($param);

        return 'invoke';

    }

}

页面输出:

string 'test' (length=4)

invoke
PHP 相关文章推荐
用在PHP里的JS打印函数
Oct 09 PHP
java EJB 加密与解密原理的一个例子
Jan 11 PHP
php 判断访客是否为搜索引擎蜘蛛的函数代码
Jul 29 PHP
php实现mysql数据库操作类分享
Feb 14 PHP
PHP连接MSSQL2008/2005数据库(SQLSRV)配置实例
Oct 22 PHP
php中get_cfg_var()和ini_get()的用法及区别
Mar 04 PHP
浅谈php提交form表单
Jul 01 PHP
Ubuntu下安装PHP的mongodb扩展操作命令
Jul 04 PHP
CodeIgniter视图使用注意事项
Jan 20 PHP
基于php(Thinkphp)+jquery 实现ajax多选反选不选删除数据功能
Feb 24 PHP
SCP远程VPS快速搬家和WDCP升级php5.3安装memcached和eaccelerator教程
Jul 27 PHP
php遍历目录下文件并按修改时间排序操作示例
Jul 12 PHP
8个PHP数组面试题
Jun 23 #PHP
php中 ob_start等函数截取标准输出的方法
Jun 22 #PHP
php发送邮件的问题详解
Jun 22 #PHP
PHP获取音频文件的相关信息
Jun 22 #PHP
php生成PDF格式文件并且加密
Jun 22 #PHP
用PHP生成excel文件到指定目录
Jun 22 #PHP
php通过baihui网API实现读取word文档并展示
Jun 22 #PHP
You might like
php字符串替换函数substr_replace()用法实例
2015/03/17 PHP
Thinkphp和onethink实现微信支付插件
2016/04/13 PHP
php基于dom实现的图书xml格式数据示例
2017/02/03 PHP
自动更新作用
2006/10/08 Javascript
web网页按比例显示图片实现原理及js代码
2013/08/09 Javascript
js获取或设置当前窗口url参数的小例子
2013/10/14 Javascript
深入理解JavaScript高级之词法作用域和作用域链
2013/12/10 Javascript
javascript计时器事件使用详解
2014/01/07 Javascript
jQuery控制元素显示、隐藏、切换、滑动的方法总结
2015/04/16 Javascript
JavaScript实现将xml转换成html table表格的方法
2015/04/17 Javascript
JavaScript中用toString()方法返回时间为字符串
2015/06/12 Javascript
JavaScript获取键盘按键的键码(参照表)
2017/01/10 Javascript
Bootstrap表单使用方法详解
2017/02/17 Javascript
解决vue router使用 history 模式刷新后404问题
2017/07/19 Javascript
vue父组件通过props如何向子组件传递方法详解
2017/08/16 Javascript
详解A标签中href=&quot;&quot;的几种用法
2017/08/20 Javascript
关于react-router/react-router-dom v4 history不能访问问题的解决
2018/01/08 Javascript
微信小程序实现全局搜索代码高亮的示例
2018/03/30 Javascript
jQuery实现点击自身以外区域关闭弹出层功能完整示例【改进版】
2018/07/31 jQuery
详解Vue项目在其他电脑npm run dev运行报错的解决方法
2018/10/29 Javascript
详解服务端预渲染之Nuxt(介绍篇)
2019/04/07 Javascript
koa+jwt实现token验证与刷新功能
2019/05/30 Javascript
jQuery实现中奖播报功能(让文本滚动起来) 简单设置数值即可
2020/03/20 jQuery
js实现小时钟效果
2020/03/25 Javascript
vue 动态组件(component :is) 和 dom元素限制(is)用法说明
2020/09/04 Javascript
讲解Python的Scrapy爬虫框架使用代理进行采集的方法
2016/02/18 Python
Django 中使用流响应处理视频的方法
2018/07/20 Python
python实现websocket的客户端压力测试
2019/06/25 Python
python程序文件扩展名知识点详解
2020/02/27 Python
pytorch 查看cuda 版本方式
2020/06/23 Python
仿CSDN Blog返回页面顶部功能实现原理及代码
2013/06/30 HTML / CSS
西雅图电动自行车公司:Rad Power Bikes
2020/02/02 全球购物
企业承诺书怎么写
2014/05/24 职场文书
信息工作经验交流材料
2014/05/28 职场文书
大学生就业协议书范本(适用于公司企业)
2014/10/07 职场文书
2015年全国“爱牙日”宣传活动总结
2015/03/23 职场文书