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初学入门
Nov 19 PHP
怎么样可以把 phpinfo()屏蔽掉?
Nov 24 PHP
强烈声明: 不要使用(include/require)_once
Jun 06 PHP
PHP生成短网址的3种方法代码实例
Jul 08 PHP
php中ob_flush函数和flush函数用法分析
Mar 18 PHP
php实现SAE上使用storage上传与下载文件的方法
Jun 29 PHP
Thinkphp3.2.3分页使用实例解析
Jul 28 PHP
thinkphp验证码的实现(form、ajax实现验证)
Jul 28 PHP
smarty模板数学运算示例
Dec 11 PHP
PHP遍历目录文件的常用方法小结
Feb 03 PHP
YII2框架中excel表格导出的方法详解
Jul 21 PHP
PHP中关于php.ini参数优化详解
Feb 28 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开发模式(简写版)
2007/03/15 PHP
完美解决PHP中文乱码
2009/11/26 PHP
PHP中用正则表达式清除字符串的空白
2011/01/17 PHP
PHP中读取照片exif信息的方法
2014/08/20 PHP
PHP生成随机密码方法汇总
2015/08/27 PHP
PHP多进程编程实例详解
2017/07/19 PHP
获取Javscript执行函数名称的方法
2006/12/22 Javascript
IE浏览器PNG图片透明效果代码
2008/09/02 Javascript
js实现从数组里随机获取元素
2015/01/12 Javascript
js阻止浏览器默认行为的简单实例
2016/05/15 Javascript
javascript特效实现——当前时间和倒计时效果的简单实例
2016/07/20 Javascript
原生js实现轮播图
2017/02/27 Javascript
html5+canvas实现支持触屏的签名插件教程
2017/05/08 Javascript
详谈for循环里面的break和continue语句
2017/07/20 Javascript
jQuery获取随机颜色的实例代码
2018/05/21 jQuery
JS Object.preventExtensions(),Object.seal()与Object.freeze()用法实例分析
2018/08/25 Javascript
vue控制多行文字展开收起的实现示例
2019/10/11 Javascript
[01:08:48]LGD vs OG 2018国际邀请赛淘汰赛BO3 第三场 8.25
2018/08/29 DOTA
Python获取CPU、内存使用率以及网络使用状态代码
2018/02/08 Python
Python中pymysql 模块的使用详解
2019/08/12 Python
pytorch实现用CNN和LSTM对文本进行分类方式
2020/01/08 Python
Python2与Python3的区别详解
2020/02/09 Python
python_mask_array的用法
2020/02/18 Python
Python基于paramunittest模块实现excl参数化
2020/04/26 Python
Python importlib模块重载使用方法详解
2020/10/13 Python
Python hashlib和hmac模块使用方法解析
2020/12/08 Python
python基于爬虫+django,打造个性化API接口
2021/01/21 Python
新英格兰最大的特色礼品连锁店:The Paper Store
2018/07/23 全球购物
PHP开发的一般流程
2013/08/13 面试题
职称自我鉴定
2013/10/15 职场文书
学校后勤人员职责
2013/12/27 职场文书
高中自我评价范文
2014/01/27 职场文书
租房协议书样本
2014/08/20 职场文书
2015年教研室工作总结范文
2015/05/23 职场文书
Python语言规范之Pylint的详细用法
2021/06/24 Python
Vue router配置与使用分析讲解
2022/12/24 Vue.js