3

我用E_STRICTon开发。扩展类时,有时会遇到以下致命错误...

严格标准:[...] 的声明应与 [...] 中的 [...] 声明兼容

...由于子方法签名与其各自的父方法签名不完全匹配。

有时,只是类的文档不准确或不是最新的(我在 PHP 的 PDO 库中遇到过这种情况)。或者,可能很少或没有文档。在任何一种情况下,下载和阅读库的 C 源代码都可能像猜测一样令人沮丧。

可以做些什么来快速解决这些错误而不抑制E_STRICT

4

2 回答 2

5

您可以使用命令行反射功能来找出预期的签名:

$ php --rc PDO
于 2012-08-15T01:44:26.310 回答
2

我发现了一篇非常有用的文章,它建议使用 PHPReflectionClass来内省父类的期望,这里是:PHP – 反射类 – 确定父方法签名

我在 Stack Overflow 上找不到提供此提示的答案,因此我决定使用文章的示例代码(我自己的扩展版本)提交这个自我回答的问题。

使用此代码段了解有关您尝试扩展的类的更多信息:

<?php

    $className = 'PDO'; // the class you're trying to extend

    echo "<pre>\n";
    echo "CLASS : $className\n\n========\n\n";
    $refClass = new ReflectionClass($className);
    foreach ($refClass->getMethods() as $refMethod) {
        echo "METHOD : " . $refMethod->getName(). "\n\n";
        echo "getNumberOfParameters()         : " . $refMethod->getNumberOfParameters() . "\n";
        echo "getNumberOfRequiredParameters() : " . $refMethod->getNumberOfRequiredParameters() . "\n";
        echo "\n";
        foreach ($refMethod->getParameters() as $refParameter) {
            echo $refParameter . "\n";
        }
        echo "\n--------\n\n";
    }
    echo "</pre>\n";

?>

PDO这输出,例如PHP 的类:

CLASS : PDO

========

METHOD : __construct

getNumberOfParameters()         : 4
getNumberOfRequiredParameters() : 3

Parameter #0 [  $dsn ]
Parameter #1 [  $username ]
Parameter #2 [  $passwd ]
Parameter #3 [  $options ]

--------

METHOD : prepare

getNumberOfParameters()         : 2
getNumberOfRequiredParameters() : 1

Parameter #0 [  $statment ]
Parameter #1 [  $options ]

--------

METHOD : beginTransaction

getNumberOfParameters()         : 0
getNumberOfRequiredParameters() : 0

[...]

请注意,在链接的文章中,人们如何看到以下条目:

string(37) "Parameter #1 [ <optional> $cache_cb ]"

我在输出中没有看到类似<optional>的标记(逐字使用作者的代码),无论是因为我使用的是不同版本的 PHP(PHP 5.3.13)还是与底层 PDO 库有关。怀疑我的问题可能与可选参数有关,我寻找另一种方法来使用这些方法来了解它们getNumberOf*Parameters(事实上我的怀疑被证明是正确的)。


当然,如果想要输出更多信息,还有很多其他有用的反射方法。例如,通过ReflectionMethod::isPrivate,ReflectionMethod::isProtected等的方法可访问性。最后,请注意该类ReflectionMethod扩展ReflectionFunctionAbstract,因此请务必检查父类的方法。

于 2012-08-15T00:05:34.310 回答