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新手谈谈我的学习心得
Feb 25 PHP
《PHP编程最快明白》第三讲:php数组
Nov 01 PHP
php读取excel文件的简单实例
Aug 26 PHP
腾讯QQ微博API接口获取微博内容
Oct 30 PHP
php将mysql数据库整库导出生成sql文件的具体实现
Jan 08 PHP
PHP异常Parse error: syntax error, unexpected T_VAR错误解决方法
May 06 PHP
PHP制作3D扇形统计图以及对图片进行缩放操作实例
Oct 23 PHP
启用Csrf后POST数据时出现的400错误
Jul 05 PHP
解读PHP中上传文件的处理问题
May 29 PHP
Centos 6.5下PHP 5.3安装ffmpeg扩展的步骤详解
Mar 02 PHP
php进程daemon化的正确实现方法
Sep 06 PHP
PHP实现财务审核通过后返现金额到客户的功能
Jul 04 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中使用memcache存储session的三种配置方法
2014/04/05 PHP
PHP获取当前页面URL函数实例
2014/10/22 PHP
在IIS下安装PHP扩展的方法(超简单)
2017/04/10 PHP
php str_replace替换指定次数的方法详解
2017/05/05 PHP
PHP数组常用函数实例小结
2018/08/20 PHP
PHP7.3.10编译安装教程
2019/10/08 PHP
jQuery结合Json提交数据到Webservice,并接收从Webservice返回的Json数据
2011/02/18 Javascript
javascript中万恶的function实例分析
2011/05/25 Javascript
在页面中js获取光标/鼠标的坐标及光标的像素坐标
2013/11/11 Javascript
jquery+ajax+C#实现无刷新操作数据库数据的简单实例
2014/02/08 Javascript
Bootstrap树形组件jqTree的简单封装
2016/01/25 Javascript
jQuery height()、innerHeight()、outerHeight()函数的区别详解
2016/05/23 Javascript
Vue.js基础知识小结
2017/01/13 Javascript
Vue和Bootstrap的整合思路详解
2017/06/30 Javascript
深入浅析Vue不同场景下组件间的数据交流
2017/08/15 Javascript
使用vue-router beforEach实现判断用户登录跳转路由筛选功能
2018/06/25 Javascript
JS实现的全选、全不选及反选功能【案例】
2019/02/19 Javascript
基于JavaScript实现留言板功能
2020/03/16 Javascript
vue实现表单未编辑或未保存离开弹窗提示功能
2020/04/08 Javascript
javascript使用Blob对象实现的下载文件操作示例
2020/04/18 Javascript
[03:48]DOTA2完美大师赛主赛事第二日精彩集锦
2017/11/24 DOTA
[01:08:17]2018DOTA2亚洲邀请赛3月29日 小组赛B组 EG VS VGJ.T
2018/03/30 DOTA
[48:27]EG vs Liquid 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
Python自动化部署工具Fabric的简单上手指南
2016/04/19 Python
详解使用python的logging模块在stdout输出的两种方法
2017/05/17 Python
Python排序搜索基本算法之选择排序实例分析
2017/12/09 Python
python特性语法之遍历、公共方法、引用
2018/08/08 Python
树莓派使用USB摄像头和motion实现监控
2019/06/22 Python
深入解析神经网络从原理到实现
2019/07/26 Python
基于python框架Scrapy爬取自己的博客内容过程详解
2019/08/05 Python
基于python实现雪花算法过程详解
2019/11/16 Python
python3爬虫中异步协程的用法
2020/07/10 Python
如何写股份合作协议书
2014/09/11 职场文书
房地产财务经理岗位职责
2015/04/08 职场文书
英语演讲开场白
2015/05/29 职场文书
小程序后台PHP版本部署运行 LNMP+WNMP
2021/04/01 Servers