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 相关文章推荐
Apache, PHP在Windows 9x/NT下的安装与配置 (一)
Oct 09 PHP
php array的学习笔记
May 16 PHP
php cc攻击代码与防范方法
Oct 18 PHP
php echo, print, print_r, sprintf, var_dump, var_expor的使用区别
Jun 20 PHP
php实例分享之通过递归实现删除目录下的所有文件详解
May 15 PHP
ThinkPHP3.1之D方法实例详解
Jun 20 PHP
在PHP站点的页面上添加Facebook评论插件的实例教程
Jan 08 PHP
PHP中header用法小结
May 23 PHP
php基于ob_start(ob_gzhandler)实现网页压缩功能的方法
Feb 18 PHP
Bootstrap+PHP实现多图上传功能实例详解
Apr 08 PHP
php微信公众号开发之关键词回复
Oct 20 PHP
PHP安装memcache扩展的步骤讲解
Feb 14 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
晶体管来复再生式二管收音机
2021/03/02 无线电
php download.php实现代码 跳转到下载文件(response.redirect)
2009/08/26 PHP
解决FastCGI 进程超过了配置的活动超时时限的问题
2013/07/03 PHP
PHP大转盘中奖概率算法实例
2014/10/21 PHP
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2611816 bytes)
2014/11/08 PHP
Zend Framework入门教程之Zend_Db数据库操作详解
2016/12/08 PHP
微信公众号开发之获取位置信息php代码
2018/06/13 PHP
Laravel框架实现超简单的分页效果示例
2019/02/08 PHP
jcarousellite.js 基于Jquery的图片无缝滚动插件
2010/12/30 Javascript
Web Inspector:关于在 Sublime Text 中调试Js的介绍
2013/04/18 Javascript
热点新闻滚动特效的js代码
2013/08/17 Javascript
深入分析下javascript中的[]()+!
2015/07/07 Javascript
为什么JavaScript没有块级作用域
2016/05/22 Javascript
AngularJS中$http服务常用的应用及参数
2016/08/22 Javascript
微信小程序 数据绑定详解及实例
2016/10/25 Javascript
移动开发之自适应手机屏幕宽度
2016/11/23 Javascript
Vue前端开发规范整理(推荐)
2018/04/23 Javascript
vue中父子组件注意事项,传值及slot应用技巧
2018/05/09 Javascript
使用JavaScript实现node.js中的path.join方法
2018/08/12 Javascript
微信小程序自定义底部弹出框动画
2020/11/18 Javascript
[01:03:38]2014 DOTA2国际邀请赛中国区预选赛5.21 CNB VS CIS
2014/05/22 DOTA
详解JavaScript编程中的window与window.screen对象
2015/10/26 Python
机器学习之KNN算法原理及Python实现方法详解
2018/07/09 Python
django中的图片验证码功能
2019/09/18 Python
解决pyecharts运行后产生的html文件用浏览器打开空白
2020/03/11 Python
python异步Web框架sanic的实现
2020/04/27 Python
有关HTML5中背景音乐的自动播放功能
2017/10/16 HTML / CSS
加拿大在线眼镜零售商:SmartBuyGlasses加拿大
2019/05/25 全球购物
入党自我鉴定范文
2013/10/04 职场文书
乡镇三项教育实施方案
2014/03/30 职场文书
大学生求职计划书
2014/04/30 职场文书
经营理念口号
2014/06/21 职场文书
考研复习计划
2015/01/19 职场文书
资金申请报告范文
2015/05/14 职场文书
张丽莉观后感
2015/06/16 职场文书
爱国主义电影观后感
2015/06/18 职场文书