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 的 __FILE__ 常量
Jan 15 PHP
PHP strtok()函数的优点分析
Mar 02 PHP
CI框架中site_url()和base_url()的区别
Jan 07 PHP
Laravel 5 框架入门(四)完结篇
Apr 09 PHP
Linux系统下PHP-FPM的安装和配置教程
Aug 17 PHP
PHP 数组遍历foreach语法结构及实例
Jun 13 PHP
PHP sleep()函数, usleep()函数
Aug 25 PHP
PHP 中TP5 Request 请求对象的实例详解
Jul 31 PHP
Laravel框架在本地虚拟机快速安装的方法详解
Jun 11 PHP
php微信公众号开发之欢迎老朋友
Oct 20 PHP
Laravel 对某一列进行筛选然后求和sum()的例子
Oct 10 PHP
PHP实现常用排序算法的方法
Feb 05 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
如何开始收听短波广播
2021/03/01 无线电
php学习之 认清变量的作用范围
2010/01/26 PHP
php 将字符串按大写字母分隔成字符串数组
2010/04/30 PHP
thinkphp验证码显示不出来的解决方法
2014/03/29 PHP
php取得字符串首字母的方法
2015/03/25 PHP
php基于mcrypt_encrypt和mcrypt_decrypt实现字符串加密解密的方法
2016/07/12 PHP
利用php + Laravel如何实现部署自动化详解
2017/10/11 PHP
PHP面向对象程序设计模拟一般面向对象语言中的方法重载(overload)示例
2019/06/13 PHP
免费空间广告万能消除代码
2006/09/04 Javascript
JQuery 遮罩层实现(mask)实现代码
2010/01/09 Javascript
javascript实现的字符串与十六进制表示字符串相互转换方法
2015/07/17 Javascript
js实现将选中值累加到文本框的方法
2015/08/12 Javascript
浅析nodejs实现Websocket的数据接收与发送
2015/11/19 NodeJs
Bootstrap每天必学之滚动监听
2016/03/16 Javascript
ES6中Generator与异步操作实例分析
2017/03/31 Javascript
jQuery实现的上传图片本地预览效果简单示例
2018/03/29 jQuery
Vue中使用clipboard实现复制功能
2018/09/05 Javascript
详解SPA中前端路由基本原理与实现方式
2018/09/12 Javascript
Javascript的this详解
2019/03/23 Javascript
有趣的JavaScript隐式类型转换操作实例分析
2020/05/02 Javascript
关于angular浏览器兼容性问题的解决方案
2020/07/26 Javascript
详解Python的hasattr() getattr() setattr() 函数使用方法
2018/07/09 Python
详解Python 中sys.stdin.readline()的用法
2019/09/12 Python
Python读写csv文件流程及异常解决
2020/10/20 Python
HTML5 Canvas鼠标与键盘事件demo示例
2013/07/04 HTML / CSS
解决HTML5中的audio在手机端和微信端的不能自动播放问题
2019/11/04 HTML / CSS
新加坡网上花店:FlowerAdvisor新加坡
2018/10/05 全球购物
摄影实习自我鉴定
2013/09/20 职场文书
党员的自我评价范文
2014/01/02 职场文书
开朗女孩的自我评价
2014/02/10 职场文书
三方股东合作协议书
2014/10/28 职场文书
2015新学期校长寄语(3篇)
2015/03/25 职场文书
2015年社区宣传工作总结
2015/05/20 职场文书
歌咏比赛口号大全
2015/12/25 职场文书
python数据分析之用sklearn预测糖尿病
2021/04/22 Python
mysql timestamp比较查询遇到的坑及解决
2021/11/27 MySQL