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 相关文章推荐
CodeIgniter php mvc框架 中国网站
May 26 PHP
php fckeditor 调用的函数
Jun 21 PHP
PHP中图片等比缩放的实例
Mar 24 PHP
php calender(日历)二个版本代码示例(解决2038问题)
Dec 24 PHP
PHP整合七牛实现上传文件
Jul 03 PHP
在CentOS上搭建LAMP+vsftpd环境的简单指南
Aug 01 PHP
php对二维数组进行相关操作(排序、转换、去空白等)
Nov 04 PHP
PHP新建类问题分析及解决思路
Nov 19 PHP
php自定义函数转换html标签示例
Sep 29 PHP
PHP实现打包zip并下载功能
Jun 12 PHP
thinkPHP5使用Rabc实现权限管理
Aug 28 PHP
Thinkphp5.0 框架视图view的比较标签用法分析
Oct 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函数
2010/01/11 PHP
PHP 修复未正常关闭的HTML标签实现代码(支持嵌套和就近闭合)
2012/06/07 PHP
深入理解javascript中return的作用
2013/12/30 Javascript
angular简介和其特点介绍
2015/01/29 Javascript
Javascript iframe交互并兼容各种浏览器的解决方法
2016/07/12 Javascript
Jquery Easyui进度条组件Progress使用详解(8)
2020/03/26 Javascript
详解前端构建工具gulpjs的使用介绍及技巧
2017/01/19 Javascript
JavaScript Uploadify文件上传实例
2017/02/28 Javascript
深究AngularJS中$sce的使用
2017/06/12 Javascript
关于Stream和Buffer的相互转换详解
2017/07/26 Javascript
php main 与 iframe 相互通讯类(js+php同域/跨域)
2017/09/14 Javascript
用vuex写了一个购物车H5页面的示例代码
2018/12/04 Javascript
vue实现条件叠加搜索的解决方法
2019/05/28 Javascript
简单学习5种处理Vue.js异常的方法
2019/06/17 Javascript
微信公众号中的JSSDK接入及invalid signature等常见错误问题分析(全面解析)
2020/04/11 Javascript
python对字典进行排序实例
2014/09/25 Python
Python捕捉和模拟鼠标事件的方法
2015/06/03 Python
Django 查询数据库并返回页面的例子
2019/08/12 Python
Python socket处理client连接过程解析
2020/03/18 Python
Python参数传递实现过程及原理详解
2020/05/14 Python
python 无损批量压缩图片(支持保留图片信息)的示例
2020/09/22 Python
python pip如何手动安装二进制包
2020/09/30 Python
python 实现ping测试延迟的两种方法
2020/12/10 Python
全球速卖通法国在线交易平台:AliExpress法国
2017/07/07 全球购物
美国最流行的男士时尚网站:Touch of Modern
2018/02/05 全球购物
当当网软件测试笔试题
2015/11/24 面试题
万年牢教学反思
2014/02/15 职场文书
优秀的应届生自荐信
2014/05/23 职场文书
个人房屋转让协议书范本
2014/10/26 职场文书
商务代表岗位职责
2015/02/15 职场文书
会计求职自荐信范文
2015/03/04 职场文书
向雷锋同志学习倡议书
2015/04/27 职场文书
预防艾滋病宣传活动总结
2015/05/09 职场文书
浪漫的婚礼主持词
2015/06/30 职场文书
车辆安全隐患排查制度
2015/08/05 职场文书
Python多线程实用方法以及共享变量资源竞争问题
2022/04/12 Python