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实现的遍历文件夹下所有文件,编辑删除
Jan 05 PHP
php按单词截取字符串的方法
Apr 07 PHP
基于OpenCart 开发支付宝,财付通,微信支付参数错误问题
Oct 01 PHP
人脸识别测颜值、测脸龄、测相似度微信接口
Apr 07 PHP
php远程下载类分享
Apr 13 PHP
php的常量和变量实例详解
Jun 27 PHP
PHP合并两个或多个数组的方法
Jan 20 PHP
ThinkPHP框架整合微信支付之刷卡模式图文详解
Apr 10 PHP
php的命名空间与自动加载实现方法
Aug 25 PHP
laravel框架的安装与路由实例分析
Oct 11 PHP
php使用redis的几种常见操作方式和用法示例
Feb 20 PHP
php连接mysql之mysql_connect()与mysqli_connect()的区别
Jul 19 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生成缩略图示例代码分享(使用gd库实现)
2014/01/20 PHP
PHP中的Memcache详解
2014/04/05 PHP
php压缩文件夹最新版
2018/07/18 PHP
php时间戳转换代码详解
2019/08/04 PHP
Javascript 函数对象的多重身份
2009/06/28 Javascript
jquery入门—访问DOM对象方法
2013/01/07 Javascript
jquery制作多功能轮播图插件
2015/04/02 Javascript
js实现精美的银灰色竖排折叠菜单
2015/05/16 Javascript
在IE8上JS实现combobox支持拼音检索功能
2016/05/23 Javascript
AngularJS表单和输入验证实例
2016/11/02 Javascript
简单实现js浮动框
2016/12/13 Javascript
vue结合Echarts实现点击高亮效果的示例
2018/03/17 Javascript
ndm:NPM的桌面GUI应用程序
2018/10/15 Javascript
JavaScript数据结构与算法之检索算法实例分析【顺序查找、最大最小值、自组织查询】
2019/02/22 Javascript
countUp.js实现数字动态变化效果
2019/10/17 Javascript
进一步了解Python中的XML 工具
2015/04/13 Python
python中的lambda表达式用法详解
2016/06/22 Python
Python读取和处理文件后缀为.sqlite的数据文件(实例讲解)
2017/06/27 Python
python高级特性和高阶函数及使用详解
2018/10/17 Python
python 获取图片分辨率的方法
2019/01/08 Python
python中的句柄操作的方法示例
2019/06/20 Python
python sqlite的Row对象操作示例
2019/09/11 Python
wxPython实现列表增删改查功能
2019/11/19 Python
一文读懂Python 枚举
2020/08/25 Python
利用css3-animation实现逐帧动画效果
2016/03/10 HTML / CSS
微信浏览器左上角返回按钮拦截功能
2017/11/21 HTML / CSS
美国最大的旗帜经销商:Carrot-Top
2018/02/26 全球购物
幼师自我鉴定范文
2013/10/01 职场文书
文史专业毕业生自荐信
2013/11/17 职场文书
成功经营餐厅的创业计划书范文
2013/12/26 职场文书
12月小学生校园广播稿
2014/02/04 职场文书
升学宴主持词
2014/04/02 职场文书
旷工检讨书大全
2015/08/15 职场文书
体育委员竞选稿
2015/11/21 职场文书
餐厅营销的秘密:为什么老顾客会流水?
2019/08/08 职场文书
CSS 实现多彩、智能的阴影效果
2021/05/12 HTML / CSS