PHP 设计模式 笔记与总结(5)PHP 魔术方法的使用

摘要:
PHP神奇方法的使用①__ get/__Set:在访问不存在的对象属性时接管对象的属性:索引。phptitle='hello';echo$obj-˃title;执行索引Php,页面输出:string'CommonObject::__set'string'命令对象::__get'hello②__ call/__CallStatic:控制PHP对象方法的调用。当执行不存在的PHP方法时,索引PHP:˂?phpnamespaceCommon;ClassObject{function__call{//$func方法名$param参数var_dump;return“magifunction”;//返回字符串作为返回值}}索引。php˂?phpnamespaceCommon;classObject{function__toString(){return__CLASS__;}}然后执行索引Php,输出:CommonObject④__ Invoke:当PHP对象作为函数执行时,魔术方法索引。php˂?

PHP 魔术方法的使用

① __get/__set:将对象的属性进行接管

当访问一个不存在的对象属性时:

index.php

<?php
define('BASEDIR',__DIR__); //定义根目录常量
include BASEDIR.'/Common/Loader.php';
spl_autoload_register('\Common\Loader::autoload');

$obj = new CommonObject();  

//在php中访问一个不存在的对象属性时
echo $obj->title;

会抛出一个错误:Notice: Undefined property: CommonObject::$title in D:practisephpdesignpsr0index.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 CommonObject();  

$obj->title = 'hello';
echo $obj->title;

执行 index.php,页面输出:

string 'CommonObject::__set' (length=20)
string 'CommonObject::__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 CommonObject();  

//当执行一个不存在的php方法时
$obj->test('hello',123);

执行 index.php 会报一个致命错误:Fatal error: Call to undefined method CommonObject::test() in D:practisephpdesignpsr0index.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
"; //返回一个字符串作为返回值
    }
}

index.php

<?php
define('BASEDIR',__DIR__); //定义根目录常量
include BASEDIR.'/Common/Loader.php';
spl_autoload_register('\Common\Loader::autoload');

$obj = new CommonObject();  

//当执行一个不存在的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
"; //返回一个字符串作为返回值        
    }
}

注意:__callStatic 方法也要声明成静态方法

index.php

<?php
define('BASEDIR',__DIR__); //定义根目录常量
include BASEDIR.'/Common/Loader.php';
spl_autoload_register('\Common\Loader::autoload');

//执行一个不存在的静态方法
echo CommonObject::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 CommonObject();

echo $obj;

此时会报错: Catchable fatal error: Object of class CommonObject could not be converted to string in D:practisephpdesignpsr0index.php on line 8

在 Object.php 中添加 __toString 方法

<?php
namespace Common;

class Object{
    function __toString() {
        return __CLASS__;
    }
}

此时再执行 index.php,输出:

CommonObject

④ __invoke:将一个 PHP 对象当成一个函数来执行时,会回调此魔术方法

index.php

<?php
define('BASEDIR',__DIR__); //定义根目录常量
include BASEDIR.'/Common/Loader.php';
spl_autoload_register('\Common\Loader::autoload');

$obj = new CommonObject();

echo $obj("test");

Object.php

<?php
namespace Common;

class Object{
    function __invoke($param) {
        var_dump($param);
        return 'invoke';
    }
}

页面输出:

string 'test' (length=4)
invoke

免责声明:文章转载自《PHP 设计模式 笔记与总结(5)PHP 魔术方法的使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ORM中的查询中的参数VMware Tanzu已融合云原生与K8s 市场前景尚不确定下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版

Nginx比apache要好,优点很多,随便去搜寻引擎找一下就能找到一大把资料,这不是我们讨论的重点,我们的重点是自己做一个运行组合!為何我不從網上下載一個別人已經封裝好的現成的版本呢?因為很多人封裝了之後就不在更新了,以後想要更新都不知道怎麼做,既然如此還不如自己好好研究一下自己封裝,將來要升級也不用求人,藝不壓身! 我说下我搭配的这个组合的特点:...

php安装pcntl扩展

下载一个同样版本的php(我的是php5.6.27,我下的是php5.6.28) wget http://hk1.php.net/get/php-5.6.28.tar.gz/from/this/mirror 解压php tar -zxvf mirror 进入php/ext/pcntl/ cd ext/pcntl/ 执行命令phpize /usr/b...

jquery datatable 参数

DataTables(http://www.datatables.net/)应该是我到目前为止见过的,功能最强大的表格解决方案(当然,不计算其它整套框架中的table控件在内)。 先把它主页上写的特性翻译罗列如下: 可变长度分页;动态过滤;多列排序,带数据类型检测功能;列宽度的智能处理;从多种数据源获取数据(DOM,js Array, ajax file,...

php中流行的rpc框架详解

什么是RPC框架? 如果用一句话概括RPC就是:远程调用框架(Remote Procedure Call) 那什么是远程调用? 我的官方群点击此处。 通常我们调用一个php中的方法,比如这样一个函数方法: localAdd(10, 20),localAdd方法的具体实现要么是用户自己定义的,要么是php库函数中自带的,也就说在localAdd方法的代码实现...

PHP的Calling Scope(::调用非静态方法)

今天在群里发现有人说,PHP可以用::调用非静态方法,一致没这么试过,发现了鸟哥的blog写了这个问题的具体解释,就搬过来: 这个问题乍看, 确实很容易让人迷惑, 但实际上, 造成这样的误解的根本原因在于: 在PHP中, 判断静态与否不是靠”::”(PAAMAYIM_NEKUDOTAYIM)符号, 而是靠calling scope. 那么, 什么是call...

php curl timeout Guzzlehttp请求超时

问题根源有2个: 1,windows上测试 2,使用了nginx 今天在搭建一个laravel项目的时候,遇到了一个问题,Apache可以正常使用,换成nginx就请求超时。排查到使用Guzzlehttp请求自己的时候出错了。 以前也遇到过类似的,当时也是在nginx上,做了一次curl,然后一直超时。 问题原因: 我猜测是php只启动了一个进程,n...