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 的ArrayAccess接口 像数组一样来访问你的PHP对象
Oct 12 PHP
ThinkPHP采用模块和操作分析
Apr 18 PHP
php动态实现表格跨行跨列实现代码
Nov 06 PHP
windows下安装php的memcache模块的方法
Apr 07 PHP
php采集神器cURL使用方法详解
Feb 19 PHP
LINUX下PHP程序实现WORD文件转化为PDF文件的方法
May 13 PHP
PHP简单实现模拟登陆功能示例
Sep 15 PHP
PHP根据树的前序遍历和中序遍历构造树并输出后序遍历的方法
Nov 10 PHP
Yii2语言国际化自动配置详解
Aug 22 PHP
PHP进阶学习之垃圾回收机制详解
Jun 18 PHP
Yii redis集合的基本使用教程
Jun 14 PHP
PHP实现rar解压读取扩展包小结
Jun 03 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 miniBB中文乱码问题解决方法
2008/11/25 PHP
Php 构造函数construct的前下划线是双的_
2009/12/08 PHP
利用PHP实现图片等比例放大和缩小的方法详解
2013/06/06 PHP
解析php中array_merge与array+array的区别
2013/06/21 PHP
php文件扩展名判断及获取文件扩展名的N种方法
2015/09/12 PHP
js获取url参数的使用扩展实例
2007/12/29 Javascript
JavaScript 动态将数字金额转化为中文大写金额
2009/05/14 Javascript
用console.table()调试javascript
2014/09/04 Javascript
JQuery实现鼠标移动图片显示描述层的方法
2015/06/25 Javascript
JavaScript、tab切换完整版(自动切换、鼠标移入停止、移开运行)
2016/01/05 Javascript
js实现把图片的绝对路径转为base64字符串、blob对象再上传
2016/12/29 Javascript
Avalonjs双向数据绑定与监听的实例代码
2017/06/23 Javascript
原生JS进行前后端同构
2018/04/22 Javascript
利用原生的JavaScript实现简单拼图游戏
2018/11/18 Javascript
cocos2dx+lua实现橡皮擦功能
2018/12/20 Javascript
iview form清除校验状态的实现
2019/09/19 Javascript
ElementUI中el-tree节点的操作的实现
2020/02/27 Javascript
javascript实现拖拽碰撞检测
2020/03/12 Javascript
浅谈Vue 函数式组件的使用技巧
2020/06/16 Javascript
[05:43]VG.R战队教练Mikasa专访:为目标从未停止战斗
2016/08/02 DOTA
[49:41]NB vs NAVI Supermajor小组赛A组 BO3 第一场 6.2
2018/06/03 DOTA
[52:41]OG vs IG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/20 DOTA
Python装饰器decorator用法实例
2014/11/10 Python
pytorch 调整某一维度数据顺序的方法
2018/12/08 Python
Python实现的服务器示例小结【单进程、多进程、多线程、非阻塞式】
2019/05/23 Python
django框架使用orm实现批量更新数据的方法
2019/06/21 Python
Django 实现图片上传和显示过程详解
2019/07/18 Python
python实现手势识别的示例(入门)
2020/04/15 Python
Python Flask框架实现简单加法工具过程解析
2020/06/03 Python
python中用Scrapy实现定时爬虫的实例讲解
2021/01/18 Python
美国时尚女装在线:Missguided
2016/12/03 全球购物
幼儿园老师寄语
2014/04/03 职场文书
学雷锋倡议书
2015/01/19 职场文书
出生公证书
2015/01/23 职场文书
Java使用jmeter进行压力测试
2021/07/09 Java/Android
CSS 使用 resize 实现图片拖拽切换预览功能(强大功能)
2021/08/23 HTML / CSS