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 02 PHP
PHP通过session id 实现session共享和登录验证的代码
Jun 03 PHP
php文字水印和php图片水印实现代码(二种加水印方法)
Dec 25 PHP
小谈php正则提取图片地址
Mar 27 PHP
让CodeIgniter数据库缓存自动过期的处理的方法
Jun 12 PHP
PHP SESSION的增加、删除、修改、查看操作
Mar 20 PHP
PHP中new static()与new self()的比较
Aug 19 PHP
遍历echsop的region表形成缓存的程序实例代码
Nov 01 PHP
浅析php如何实现爬取数据原理
Sep 27 PHP
php多进程应用场景实例详解
Jul 22 PHP
Laravel登录失败次数限制的实现方法
Aug 26 PHP
PHP高并发和大流量解决方案整理
Mar 09 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性能优化的介绍
2013/06/20 PHP
Thinkphp中Create方法深入探究
2014/06/16 PHP
用PHP的socket实现客户端到服务端的通信实例详解
2017/02/04 PHP
PHP之多条件混合筛选功能的实现方法
2019/10/09 PHP
Avengerls vs Newbee BO3 第二场2.18
2021/03/10 DOTA
javascript 写的一个简单的timer
2009/07/30 Javascript
js为鼠标添加右击事件防止默认的右击菜单弹出
2013/07/29 Javascript
使用命令对象代替switch语句的写法示例
2015/02/28 Javascript
JavaScript+html5 canvas绘制缤纷多彩的三角形效果完整实例
2016/01/26 Javascript
javascript的列表切换【实现代码】
2016/05/03 Javascript
Javascript计算二维数组重复值示例代码
2016/12/18 Javascript
jQuery实现圣诞节礼物传送(花式轮播)
2016/12/25 Javascript
MUI实现上拉加载和下拉刷新效果
2017/06/30 Javascript
bootstrap select下拉搜索插件使用方法详解
2017/11/23 Javascript
JavaScript笛卡尔积超简单实现算法示例
2018/07/30 Javascript
[16:43]Heroes19_剃刀(完美)
2014/10/31 DOTA
Python正则表达式介绍
2012/08/06 Python
pyside写ui界面入门示例
2014/01/22 Python
Python基本数据类型详细介绍
2014/03/11 Python
疯狂上涨的Python 开发者应从2.x还是3.x着手?
2017/11/16 Python
python使用os.listdir和os.walk获得文件的路径的方法
2017/12/16 Python
Python HTML解析模块HTMLParser用法分析【爬虫工具】
2019/04/05 Python
Python3.6中Twisted模块安装的问题与解决
2019/04/15 Python
详解Python3除法之真除法、截断除法和下取整对比
2019/05/23 Python
django ajax发送post请求的两种方法
2020/01/05 Python
python 最简单的实现适配器设计模式的示例
2020/06/30 Python
Pandas DataFrame求差集的示例代码
2020/12/13 Python
奥林匹亚体育:Olympia Sports
2020/12/30 全球购物
函授毕业生的自我鉴定
2013/11/26 职场文书
《赵州桥》教学反思
2014/02/17 职场文书
财务部总监岗位职责
2014/03/12 职场文书
勤俭节约演讲稿
2014/05/08 职场文书
团代会闭幕词
2015/01/28 职场文书
python 如何在 Matplotlib 中绘制垂直线
2021/04/02 Python
java设计模式--建造者模式详解
2021/07/21 Java/Android
Oracle 触发器trigger使用案例
2022/02/24 Oracle