1

我的代码有奇怪的问题。我的代码与下面的代码几乎相同(我没有提供实际代码,因为它是一个有点大的库,有很多动态生成(基于路径路由等选择类,即框架))。

代码解释:

ClassA代表当前的路由对象。包含控制器、路由字符串等。

ScriptAClassAction是调度程序,检查路由是否包含执行和运行所有内容所必需的所有内容,控制器是否存在$!empty(reflection)以及操作是否存在于控制器中$reflection->hasMethod('hello')

在我的世界中,如果两个条件都意味着(并且不是),则应该触发父级 if或者应该触发 else ,这是检查哪些检查失败。在执行时,我看到第一个检查通过(我认为这是 PHP 中的一个错误) ,然后触发else,然后是第二个if

我在想这可能是 PHP 中的一个错误,但我很怀疑。有人看到我在凌晨 1:50 想念的东西吗?

PHP 5.3.27 启用了 xDebug(没有其他扩展)和 Apache 2.2.25(我相信 Apache 在这里无关,但是..),Windows 7 x86 Home Premium

类A.php

class A
{
    public function init()
    {
        print 'Init called';
    }

    public function preDispatch()
    {
        print 'Predispatch called';
    }

    public function indexAction()
    {
        print 'Hello world';
    }

    public function postDispatch()
    {
        print "Post dispatch";
    }
}

ScriptAClassAction.php

require 'ClassA.php';

$class = new A();
$reflection = new ReflectionClass($class);
if (!empty($reflection) && $reflection->hasMethod('indexAction')) {
    if ($reflection->hasMethod('init')) $class->init($request, $response); //Prints 'Init called'
    if ($reflection->hasMethod('preDispatch')) $class->preDispatch(); // 'Predispatch called' 
    $class->indexAction();
    if ($reflection->hasMethod('postDispatch')) $class->postDispatch(); // 'post dispatch called'..
} else {
    if (!$reflection) // I know this might not be the best check but..
        print "Not a valid class supplied";

    if (false == $reflection->hasMethod('indexAction')) // True trigger
        print "Supplied class does not have any manners and does not greet you :D";
        // This is the expected output and it should be the only output
}

** 输出 **

Init 称为 Predispatch 称为 Postdospatch 称为 Supplied 类没有任何礼仪,也不会打招呼:D

4

1 回答 1

2

在语句中添加括号if将解决问题。此外,您不必测试$reflection变量是否为空。它永远是一个实例。

就像@traq 提到的那样,最好创建接口来识别具有某些行为的类。

interface DispatchAware {
    public function preDispatch();
    public function postDispatch();
}

class A implements DispatchAware { ... }

现在您不必检查可能存在的每种方法。当一个类实现一个接口时,你就会知道它的存在。

您调度的代码现在可能看起来像:

$action = 'indexAction';

$a = new A();

if ($a instanceof DispatchAware) {
    $a->preDispatch();
}

try {
    $r = new ReflectionClass($a);
    $method = $r->getMethod($action);
    $method->invoke($a, $request, $response);
} catch (Exception $e) {
    methodNotFoundError();
}

if ($a instanceof DispatchAware) {
    $a->postDispatch();
}

我也删除了该init()方法。这样做的原因是控制器类型的对象通常不需要保持状态。这就是为什么$request$response作为参数传递给操作方法。

于 2013-08-25T07:29:13.280 回答