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利用cookie实现访问次数统计代码
May 19 PHP
php处理斐波那契数列非递归方法
Feb 04 PHP
PHP 第二节 数据类型之数值型
Apr 28 PHP
深入Memcache的Session数据的多服务器共享详解
Jun 13 PHP
php获取域名的google收录示例
Mar 24 PHP
CodeIgniter安全相关设置汇总
Jul 03 PHP
destoon出现验证码不显示时的紧急处理方法
Aug 22 PHP
PHP经典面试题集锦
Mar 19 PHP
Smarty模板引擎缓存机制详解
May 23 PHP
Laravel中Facade的加载过程与原理详解
Sep 22 PHP
laravel中短信发送验证码的实现方法
Apr 25 PHP
Laravel框架使用Seeder实现自动填充数据功能
Jun 13 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加密解密示例分享
2014/01/29 PHP
使用php语句将数据库*.sql文件导入数据库
2014/05/05 PHP
php查询mssql出现乱码的解决方法
2014/12/29 PHP
php实现用户注册密码的crypt加密
2017/06/08 PHP
Linux下源码包安装Swoole及基本使用操作图文详解
2019/04/02 PHP
Laravel框架处理用户的请求操作详解
2019/12/20 PHP
jquery遍历checkbox的注意事项说明
2014/02/21 Javascript
WordPress中利用AJAX技术进行评论提交的实现示例
2016/01/12 Javascript
DIV+CSS+jQ实现省市联动可扩展
2016/06/22 Javascript
JS中setTimeout和setInterval的最大延时值详解
2017/02/13 Javascript
jQuery实现列表的增加和删除功能
2018/06/14 jQuery
解决angularjs service中依赖注入$scope报错的问题
2018/10/02 Javascript
electron实现qq快捷登录的方法示例
2018/10/22 Javascript
jQuery实现网页拼图游戏
2020/04/22 jQuery
小程序云开发获取不到数据库记录的解决方法
2019/05/18 Javascript
Electron 调用命令行(cmd)
2019/09/23 Javascript
以Flask为例讲解Python的框架的使用方法
2015/04/29 Python
python避免死锁方法实例分析
2015/06/04 Python
pandas 实现字典转换成DataFrame的方法
2018/07/04 Python
python学生信息管理系统(完整版)
2020/04/05 Python
Python OOP类中的几种函数或方法总结
2019/02/22 Python
Python3使用Matplotlib 绘制精美的数学函数图形
2019/04/11 Python
pytorch梯度剪裁方式
2020/02/04 Python
python画环形图的方法
2020/03/25 Python
Python使用pycharm导入pymysql教程
2020/09/16 Python
Python的collections模块真的很好用
2021/03/01 Python
CSS3 3D位移translate效果实例介绍
2016/05/03 HTML / CSS
西班牙鞋子和箱包在线销售网站:zapatos.es
2020/02/17 全球购物
商务英语应届生自我鉴定
2013/12/08 职场文书
捐助感谢信
2015/01/22 职场文书
运动与健康自我评价
2015/03/09 职场文书
总经理2015中秋节致辞
2015/07/29 职场文书
医学生自荐信范文(2016精选篇)
2016/01/28 职场文书
Python实现PIL图像处理库绘制国际象棋棋盘
2021/07/16 Python
win sever 2022如何占用操作主机角色
2022/06/25 Servers
SQL Server数据库的三种创建方法汇总
2023/05/08 MySQL