PHP代码问题或错误

PHP代码问题或错误,php,Php,我的代码有奇怪的问题。我的代码与下面的代码几乎相同(我没有提供实际的代码b`z,因为它是一个有很多动态生成的小库(根据路径路由等选择类,即框架)) 守则解释如下: ClassA表示当前路由对象。包含控制器、路由字符串等 ScriptAClassAction是调度器,检查路由是否具有执行所需的所有内容,并运行所有内容,控制器是否存在$!空(反射)并且操作是否存在于控制器中$reflection->hasMethod('hello') 在我的世界中,如果两个条件都是有效的(而不是有效的),则应触发父

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

守则解释如下:

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

ScriptAClassAction是调度器,检查路由是否具有执行所需的所有内容,并运行所有内容,控制器是否存在
$!空(反射)
并且操作是否存在于控制器中
$reflection->hasMethod('hello')

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

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

PHP5.3.27启用了xDebug(没有其他扩展)和Apache2.2.25(我认为Apache2.2.25与此无关,但是…),Windows7x86HomePremium

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";
    }
}
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
}
ScriptAClassAction.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";
    }
}
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名为Postdospatch名为Supplied class 没有任何礼貌,不向你打招呼: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方法的原因。

我对您试图实现的目标有点困惑。此外,当您构造一个新对象(
$var=new Class();
)时,您总是会在变量中得到一个实例,除非出现一些关键问题……在这种情况下,代码的其余部分不会执行。换句话说,您的
if(!empty($reflection)
if(!$reflection)
检查完全没有意义。您的
hasMethod()中发生了什么
?这可能是你误报的原因。我得到的
提供的类没有任何礼貌,也没有向你打招呼:D
强烈回响,据我所知这是预期的行为。请让你的问题更明确。@victorantunes:这不是OP的hasMethod()。这是问题的一部分。我得到“Init called…”输出也一样,这是我所期望的。但是,与其尝试“修复”在这段代码中,我建议您使用一个-您试图确保一个特定的类包含特定的方法;这正是接口的用途。比如,也许。接口不是一个可选的atm,因为这个概念通常取自ZF1.X。前调度和后调度不是必需的,而是可选的。无论如何,感谢您的发布我相信这个例子会帮助我更清楚地了解编码。实现接口也是可选的。如果类只希望实现preDispatch,那么它可以为其他类提供空方法。或者,您可以将其设置为抽象类。