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安全编程之加密功能
Oct 09 PHP
杏林同学录(六)
Oct 09 PHP
PHP的面试题集
Nov 19 PHP
彻底杜绝PHP的session cookie错误
Aug 09 PHP
PHP 程序员的调试技术小结
Nov 15 PHP
php mysql 判断update之后是否更新了的方法
Jan 10 PHP
深入php之规范编程命名小结
May 15 PHP
PHP中加密解密函数与DES加密解密实例
Oct 17 PHP
php实现的IMEI限制的短信验证码发送类
May 05 PHP
thinkphp命名空间用法实例详解
Dec 30 PHP
PHP下的浮点运算不准的解决方法
Oct 27 PHP
基于swoole实现多人聊天室
Jun 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
用PHP调用Oracle存储过程
2006/10/09 PHP
很实用的一个完整email发送程序
2006/10/09 PHP
php+javascript的日历控件
2009/11/19 PHP
PHP MYSQL实现登陆和模糊查询两大功能
2016/02/05 PHP
浅谈PHP Cookie处理函数
2016/06/10 PHP
Laravel实现通过blade模板引擎渲染视图
2019/10/25 PHP
使用Apache的rewrite
2021/03/09 Servers
用jQuery模拟select下拉框的简单示例代码
2014/01/26 Javascript
jQuery+ajax实现动态执行脚本的方法
2015/01/27 Javascript
jQuery实现跨域
2015/02/03 Javascript
弹出遮罩层后禁止滚动效果【实现代码】
2016/04/29 Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
2016/05/24 Javascript
Angular.js去除页面中显示的空行方法示例
2017/03/30 Javascript
详解基于 Nuxt 的 Vue.js 服务端渲染实践
2017/10/24 Javascript
Vue 动态设置路由参数的案例分析
2018/04/24 Javascript
JS选取DOM元素常见操作方法实例分析
2018/12/10 Javascript
小程序和web画三角形实现解析
2019/09/02 Javascript
js+springMVC 提交数组数据到后台的实例
2019/09/21 Javascript
javascript设计模式之迭代器模式
2020/01/30 Javascript
[01:11:27]2018DOTA2亚洲邀请赛小组赛 A组加赛 Newbee vs Optic
2018/04/03 DOTA
Pycharm 创建 Django admin 用户名和密码的实例
2018/05/30 Python
Python 离线工作环境搭建的方法步骤
2019/07/29 Python
python网络爬虫 Scrapy中selenium用法详解
2019/09/28 Python
python中的函数递归和迭代原理解析
2019/11/14 Python
Pytorch之parameters的使用
2019/12/31 Python
跑步、骑行和铁人三项的高性能眼镜和服装:ROKA
2018/07/06 全球购物
可爱的童装和鞋子:Fabkids
2019/08/16 全球购物
Keds加拿大官网:购买帆布运动鞋和皮鞋
2019/09/26 全球购物
印尼在线旅游门户网站:NusaTrip
2019/11/01 全球购物
美国名牌香水折扣网站:Hottperfume
2021/02/10 全球购物
教职工代表大会主持词
2014/04/01 职场文书
中学生操行评语
2014/04/24 职场文书
汽车运用工程专业求职信
2014/06/18 职场文书
高中学生自我评价范文
2014/09/23 职场文书
县委务虚会发言材料
2014/10/20 职场文书
面试通知短信
2015/04/20 职场文书