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静态新闻列表自动生成代码
Jun 14 PHP
php截取utf-8中文字符串乱码的解决方法
Mar 29 PHP
PHP读取网页文件内容的实现代码(fopen,curl等)
Jun 23 PHP
PHP 设计模式之观察者模式介绍
Feb 22 PHP
php定时计划任务的实现方法详解
Jun 06 PHP
PHP通过内置函数memory_get_usage()获取内存使用情况
Nov 20 PHP
PHP实现返回JSON和XML的类分享
Jan 28 PHP
php根据用户名和手机号查询是否存在手机号码
Feb 16 PHP
php实现姓名根据首字母排序的类与方法(实例代码)
May 16 PHP
PHP实现的ID混淆算法类与用法示例
Aug 10 PHP
微信公众平台开发教程⑥ 微信开发集成类的使用图文详解
Apr 10 PHP
Laravel6.18.19如何优雅的切换发件账户
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相当简单的分页类
2008/10/02 PHP
深入mysql_fetch_row()与mysql_fetch_array()的区别详解
2013/06/05 PHP
使用php清除bom示例
2014/03/03 PHP
关于PHP中协程和阻塞的一些理解与思考
2017/08/11 PHP
javascript jQuery $.post $.ajax用法
2008/07/09 Javascript
javascript学习笔记(三)显示当时时间的代码
2011/04/08 Javascript
用js读、写、删除Cookie代码分享及详细注释说明
2014/06/05 Javascript
解释&amp;&amp;和||在javascript中的另类用法
2014/07/28 Javascript
javascript实现设置、获取和删除Cookie的方法
2015/06/01 Javascript
HTML5基于Tomcat 7.0实现WebSocket连接并实现简单的实时聊天
2016/10/31 Javascript
微信小程序 在线支付功能的实现
2017/03/14 Javascript
微信小程序注册60s倒计时功能 使用JS实现注册60s倒计时功能
2017/08/16 Javascript
Bootstrap一款超好用的前端框架
2017/09/25 Javascript
详细分析jsonp的原理和实现方式
2017/11/20 Javascript
Vue.js组件间的循环引用方法示例
2017/12/27 Javascript
layui-laydate时间日历控件使用方法详解
2018/11/15 Javascript
JavaScript模块管理的简单实现方式详解
2019/06/15 Javascript
IE11下CKEditor在Bootstrap Modal中下拉问题的解决
2019/09/25 Javascript
Vue实现可移动水平时间轴
2020/06/29 Javascript
javascript递归函数定义和用法示例分析
2020/07/22 Javascript
解决Vue使用bus总线时,第一次路由跳转时数据没成功传递问题
2020/07/28 Javascript
vue3使用vue-count-to组件的实现
2020/12/25 Vue.js
[03:06]V社市场总监Dota2项目负责人Erik专访:希望更多中国玩家加入DOTA2
2014/07/11 DOTA
python基础教程之获取本机ip数据包示例
2014/02/10 Python
用python代码做configure文件
2014/07/20 Python
python实现简单遗传算法
2018/03/19 Python
在cmd命令行里进入和退出Python程序的方法
2018/05/12 Python
Python实现手写一个类似django的web框架示例
2018/07/20 Python
Django model序列化为json的方法示例
2018/10/16 Python
Python批量生成特定尺寸图片及图画任意文字的实例
2019/01/30 Python
浅谈pc和移动端的响应式的使用
2019/01/03 HTML / CSS
企业人事任命书
2014/06/05 职场文书
青年文明号口号
2014/06/17 职场文书
群众路线教育实践活动剖析材料
2014/09/30 职场文书
商家认证委托书格式
2014/10/16 职场文书
幼儿园教师岗位职责
2015/04/02 职场文书