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 相关文章推荐
xml+php动态载入与分页
Oct 09 PHP
我的论坛源代码(五)
Oct 09 PHP
关于shopex同步ucenter的redirect问题,导致script不运行
Apr 10 PHP
解析VS2010利用VS.PHP插件调试PHP的方法
Jul 19 PHP
PHP+ajaxfileupload+jcrop插件完美实现头像上传剪裁
Jun 09 PHP
ThinkPHP字符串函数及常用函数汇总
Jul 18 PHP
php用户注册时常用的检验函数实例总结
Dec 22 PHP
实现PHP+Mysql无限分类的方法汇总
Mar 02 PHP
Apache启动报错No space left on device: AH00023该怎么解决
Oct 16 PHP
PHP请求远程地址设置超时时间的解决方法
Oct 29 PHP
关于laravel后台模板laravel-admin select框的使用详解
Oct 03 PHP
laravel框架邮箱认证实现方法详解
Nov 22 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中$_REQUEST、$_POST、$_GET的区别和联系小结
2011/11/23 PHP
Yii2基于Ajax自动获取表单数据的方法
2016/08/10 PHP
php 生成签名及验证签名详解
2016/10/26 PHP
thinkPHP多语言切换设置方法详解
2016/11/11 PHP
php使用lua+redis实现限流,计数器模式,令牌桶模式
2019/04/04 PHP
一个简单的javascript类定义例子
2009/09/12 Javascript
JS实现可改变列宽的table实例
2013/07/02 Javascript
javascript获取鼠标位置部分的实例代码(兼容IE,FF)
2013/08/05 Javascript
jQuery实现高亮显示的方法
2015/03/10 Javascript
学习JavaScript设计模式(封装)
2015/11/26 Javascript
Google 地图叠加层实例讲解
2016/08/06 Javascript
Javascript仿京东放大镜的效果
2017/03/01 Javascript
多个上传文件用js验证文件的格式和大小的方法(推荐)
2017/03/09 Javascript
input file样式修改以及图片预览删除功能详细概括(推荐)
2017/08/17 Javascript
vue.js移动端app之上拉加载以及下拉刷新实战
2017/09/11 Javascript
Vue监听滚动实现锚点定位(双向)示例
2019/11/13 Javascript
javascript 原型与原型链的理解及实例分析
2019/11/23 Javascript
浅析Python3爬虫登录模拟
2018/02/07 Python
python解析json串与正则匹配对比方法
2018/12/20 Python
在cmd中查看python的安装路径方法
2019/07/03 Python
pandas中ix的使用详细讲解
2020/03/09 Python
Python接口测试数据库封装实现原理
2020/05/09 Python
Monnier Freres中文官网:法国领先的奢侈品配饰在线零售商
2017/11/01 全球购物
加拿大奢华时装品牌:Mackage
2018/01/10 全球购物
用缩写的指针比较"if(p)" 检查空指针是否可靠?如果空指针的内部表达不是0会怎么样?
2014/01/05 面试题
小学教育毕业生自荐信
2013/11/18 职场文书
职务聘任书范文
2014/03/29 职场文书
《闻一多先生的说和做》教学反思
2014/04/28 职场文书
社区志愿者培训方案
2014/06/10 职场文书
邓小平理论心得体会
2014/09/09 职场文书
保证书格式
2015/01/16 职场文书
医院保洁员岗位职责
2015/02/13 职场文书
党支部审查意见
2015/06/02 职场文书
复活读书笔记
2015/06/29 职场文书
Go标准容器之Ring的使用说明
2021/05/05 Golang
总结一下关于在Java8中使用stream流踩过的一些坑
2021/06/24 Java/Android