PHP代码问题或错误


Problems with PHP code or a bug

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

代码解释:

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

ScriptAClassAction是调度器,检查路由是否具有执行和运行所有内容所需的一切,控制器是否存在$!empty(reflection),操作是否存在于控制器$reflection->hasMethod('hello')中。

在我的世界里,如果两个条件都是(而不是),则父if应该被触发,或者其他条件应该被触发(即检查哪些检查失败)。在执行时,我看到第一次检查通过(我认为这是PHP中的一个错误),之后触发else,然后触发第二次if

我认为这可能是PHP中的一个错误,但我对此表示怀疑。有人看到我在凌晨1点50分错过的东西吗?

PHP 5.3.27启用了xDebug(没有其他扩展)&Apache 2.2.25(我认为Apache在这里无关紧要,但..),Windows 7 x86 Home Premium

ClassA.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
}

**输出**

名为Predispatch的Init名为Postdosplatch的Supplied类没有任何礼貌,也不问候你:D

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作为参数传递给action方法的原因。