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实现ping
Oct 09 PHP
php学习笔记 类的声明与对象实例化
Jun 13 PHP
PHP表单提交表单名称含有点号(.)则会被转化为下划线(_)
Dec 14 PHP
解析array splice的移除数组中指定键的值,返回一个新的数组
Jul 02 PHP
CodeIgniter框架过滤HTML危险代码
Jun 12 PHP
php几个预定义变量$_SERVER用法小结
Nov 07 PHP
PHP SPL标准库之文件操作(SplFileInfo和SplFileObject)实例
May 11 PHP
PHP编写daemon process详解及实例代码
Sep 30 PHP
golang实现php里的serialize()和unserialize()序列和反序列方法详解
Oct 30 PHP
PHP fprintf()函数用法讲解
Feb 16 PHP
PHP使用HTML5 FileApi实现Ajax上传文件功能示例
Jul 01 PHP
Yii实现微信公众号场景二维码的方法实例
Aug 30 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+DBM的同学录程序(4)
2006/10/09 PHP
dedecms采集中可以过滤多行代码的正则表达式
2007/03/17 PHP
php设计模式 State (状态模式)
2011/06/26 PHP
解析PHP中如何将数组变量写入文件
2013/06/06 PHP
memcache命令启动参数中文解释
2014/01/13 PHP
一组PHP加密解密函数分享
2014/06/05 PHP
jQuery 图像裁剪插件Jcrop的简单使用
2009/05/22 Javascript
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
2011/03/28 Javascript
JavaScript中的style.cssText使用教程
2014/11/06 Javascript
javascript中tostring()和valueof()的用法及两者的区别
2015/11/16 Javascript
javascript实现下拉提示选择框
2015/12/29 Javascript
JQuery 封装 Ajax 常用方法(推荐)
2017/05/21 jQuery
移动端Ionic App 资讯上下循环滚动的实现代码(跑马灯效果)
2017/08/29 Javascript
Vue动态路由缓存不相互影响的解决办法
2019/02/19 Javascript
vue父组件触发事件改变子组件的值的方法实例详解
2019/05/07 Javascript
解决vuex刷新状态初始化的方法实现
2019/08/15 Javascript
解决LayUI加上form.render()下拉框和单选以及复选框不出来的问题
2019/09/27 Javascript
Python实现国外赌场热门游戏Craps(双骰子)
2015/03/31 Python
Python实现base64编码的图片保存到本地功能示例
2018/06/22 Python
基于python实现聊天室程序
2018/07/27 Python
python跳出双层for循环的解决方法
2019/06/24 Python
python读取.mat文件的数据及实例代码
2019/07/12 Python
python爬虫库scrapy简单使用实例详解
2020/02/10 Python
Django微信小程序后台开发教程的实现
2020/06/03 Python
介绍一下MYSQL常用的优化技巧
2012/10/25 面试题
网络专业学生个人的自我评价
2013/12/16 职场文书
七年级英语教学反思
2014/01/15 职场文书
挂科检讨书范文
2014/02/20 职场文书
师范生自荐信模板
2014/05/28 职场文书
助理政工师申报材料
2014/06/03 职场文书
安全施工标语
2014/06/07 职场文书
水利专业大学生职业生涯规划书范文
2014/09/17 职场文书
营业员岗位职责
2015/02/11 职场文书
公务员年度考核登记表个人总结
2015/02/12 职场文书
2015年技术工作总结范文
2015/04/20 职场文书
工作时间调整通知
2015/04/24 职场文书