PHP5 权威编程 4.5.4使用映射执行授权模式 代码改进

本文探讨了在PHP中实现类方法的动态调用机制,通过改进原始代码,实现了对多个类实例方法的安全调用,避免了因方法不存在引发的异常,确保了代码的稳定性和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原始代码:

<?php
class ClassOne{
    function callClassOne(){
        print "In Class One\n";
    }
}

class ClassTwo{
    function callClassTwo(){
        print "In Class Two\n";
    }
}

class ClassOneDelegator{
    private $target = array();

    function __construct()
    {
        $this->target[] = new ClassOne();
    }

    function addObject($obj){
        $this->target[] = $obj;
    }

    function __call($name, $arguments)
    {
        foreach($this->target as $obj){
            $r = new ReflectionClass($obj);
            if($method = $r->getMethod($name)){
                if($method->isPublic() && !$method->isAbstract()){
                    return $method->invoke($obj, $args);
                }
            };
        }
        return false;
    }
}

$objz = new ClassOneDelegator();
$objz->addObject(new ClassTwo());
$objz->callClassOne();
$objz->callClassTwo();


按照书中的代码运行会报以下错误,

D:\phpstudy_pro\WWW>php index.php
In Class One

Fatal error: Uncaught ReflectionException: Method callClassTwo does not exist in D:\phpstudy_pro\WWW\index.php on line 30

ReflectionException: Method callClassTwo does not exist in D:\phpstudy_pro\WWW\index.php on line 30

Call Stack:
    0.0000     358608   1. {main}() D:\phpstudy_pro\WWW\index.php:0
    0.0000     359152   2. ClassOneDelegator->callClassTwo() D:\phpstudy_pro\WWW\index.php:43
    0.0000     359208   3. ClassOneDelegator->__call() D:\phpstudy_pro\WWW\index.php:43
    0.0000     359320   4. ReflectionClass->getMethod() D:\phpstudy_pro\WWW\index.php:30

 

正常出来In Class One,但是In Class Two不能出来

原因在于这一行

if($method = $r->getMethod($name)){
ReflectionClass的实例$r 在执行getMethod方法时,首先会尝试调用ClassOne对象的相关方法,如果方法名称不存在,就会引发异常,直接就导致代码不能继续运行下去.所以考虑到加入异常处理以便跳过,使之能够调用下一个ClassTwo实例的callClassTwo方法.改进出下
<?php
class ClassOne{
    function callClassOne(){
        print "In Class One\n";
    }
}

class ClassTwo{
    function callClassTwo(){
        print "In Class Two\n";
    }
}

class ClassOneDelegator{
    private $target = array();

    function __construct()
    {
        $this->target[] = new ClassOne();
    }

    function addObject($obj){
        $this->target[] = $obj;
    }

    function __call($name, $arguments)
    {
        // TODO: Implement __call() method.
        foreach($this->target as $obj){
            $r = new ReflectionClass($obj);
            try{
                if($method = $r->getMethod($name)){
                    if($method->isPublic() && !$method->isAbstract()){
                        return $method->invoke($obj, $args);
                    }
                };
            }catch (Exception $e){
                //
            }
        }
        return false;
    }
}

$objz = new ClassOneDelegator();
$objz->addObject(new ClassTwo());
$objz->callClassOne();
$objz->callClassTwo();

运行的效果,达到书中的示例效果.
D:\phpstudy_pro\WWW>php z.php
In Class One
In Class Two

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值