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语法(3)
Oct 09 PHP
模仿OSO的论坛(一)
Oct 09 PHP
深入php-fpm的两种进程管理模式详解
Jun 03 PHP
PHP对接微信公众平台消息接口开发流程教程
Mar 25 PHP
php中的四舍五入函数代码(floor函数、ceil函数、round与intval)
Jul 14 PHP
PHP-Java-Bridge使用笔记
Sep 22 PHP
PHP下载远程图片并保存到本地方法总结
Jan 22 PHP
php打包压缩文件之ZipArchive方法用法分析
Apr 30 PHP
php中Redis的应用--消息传递
Mar 28 PHP
PHP编程实现脚本异步执行的方法
Aug 09 PHP
PHP使用栈解决约瑟夫环问题算法示例
Aug 27 PHP
php实现微信公众号创建自定义菜单功能的实例代码
Jun 11 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
Laravel框架数据库CURD操作、连贯操作总结
2014/09/03 PHP
php中header设置常见文件类型的content-type
2015/06/23 PHP
PHPMailer使用QQ邮箱实现邮件发送功能
2017/08/18 PHP
JavaScript入门教程(5) js Screen屏幕对象
2009/01/31 Javascript
Jquery实现的一种常用高亮效果示例代码
2014/01/28 Javascript
js判断url是否有效的两种方法
2014/03/04 Javascript
浅谈jQuery中对象遍历.eq().first().last().slice()方法
2014/11/26 Javascript
JavaScript通过字典进行字符串翻译转换的方法
2015/03/19 Javascript
基于MVC4+EasyUI的Web开发框架形成之旅之界面控件的使用
2015/12/16 Javascript
一个字符串中出现次数最多的字符 统计这个次数【实现代码】
2016/04/29 Javascript
用纯Node.JS弹出Windows系统消息提示框实例(MessageBox)
2017/05/17 Javascript
javascript简单写的判断电话号码实例
2017/05/24 Javascript
实例讲解Vue.js中router传参
2018/04/22 Javascript
Iview Table组件中各种组件扩展的使用
2018/10/20 Javascript
利用jqgrid实现上移下移单元格功能
2018/11/07 Javascript
vue 项目build错误异常的解决方法
2019/04/22 Javascript
微信小程序纯文本实现@功能
2020/04/08 Javascript
[07:37]DOTA2-DPC中国联赛2月2日Recap集锦
2021/03/11 DOTA
Python json模块使用实例
2015/04/11 Python
Python的条件语句与运算符优先级详解
2015/10/13 Python
Python爬虫番外篇之Cookie和Session详解
2017/12/27 Python
pandas对指定列进行填充的方法
2018/04/11 Python
django 将model转换为字典的方法示例
2018/10/16 Python
利用Python实现原创工具的Logo与Help
2018/12/03 Python
在Pycharm中执行scrapy命令的方法
2019/01/16 Python
更新修改后的Python模块方法
2019/03/03 Python
解决pytorch 的state_dict()拷贝问题
2021/03/03 Python
整理HTML5中支持的URL编码与字符编码
2016/02/23 HTML / CSS
巴西宠物店在线:Geração Pet
2017/05/31 全球购物
新闻专业个人求职信
2013/12/19 职场文书
《画》教学反思
2014/04/14 职场文书
公司授权委托书样本
2014/09/15 职场文书
2014年青年志愿者工作总结
2014/12/09 职场文书
少先队辅导员事迹材料
2014/12/24 职场文书
2015年父亲节寄语
2015/03/23 职场文书
vue实现水波涟漪效果的点击反馈指令
2021/05/31 Vue.js