Andrew Cheong
Andrew Cheong

Reputation: 30273

PHP: Strict Standards: Declaration of [...] should be compatible with that of [...] in [...]

I develop with E_STRICT on. When extending a class I sometimes encounter the following fatal error...

Strict Standards: Declaration of [...] should be compatible with that of [...] in [...]

...due to a child method signature not exactly matching its respective parent method signature.

Sometimes, it's simply that the class's documentation isn't accurate or up to date (I've encountered this in PHP's PDO library). Or, there may be little or no documentation. And in either case, downloading and reading the library's C source code can be as frustrating as guesswork.

What can one do to quickly work through these errors, without suppressing E_STRICT?

Upvotes: 3

Views: 8956

Answers (2)

Ja͢ck
Ja͢ck

Reputation: 173552

You can use the command-line reflection feature to find out the expected signature:

$ php --rc PDO

Upvotes: 5

Andrew Cheong
Andrew Cheong

Reputation: 30273

I found an extremely useful article that suggests using PHP's ReflectionClass to introspect what a parent class expects, here: PHP – Reflection Class – Determine Parent Method Signature.

I found no answer providing this tip on Stack Overflow, so I decided to submit this self-answered question with (my own extended version of) the article's sample code.

Use this snippet to learn more about the class you're trying to extend:

<?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";

?>

This outputs, for PHP's PDO class for example:

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

[...]

Note how, in the linked article, one sees entries like:

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

I did not see similar <optional> markers in my output (using the author's code verbatim), whether it's because I was using a different version of PHP (PHP 5.3.13) or it's something about the underlying PDO library. Suspecting that my issue might have something to do with optional parameters, I sought an alternative way to find out about them using the getNumberOf*Parameters methods(—and indeed my suspicion proved correct).


There are plenty of other useful reflection methods if one desires to output more information, of course. For example, method accessibility via ReflectionMethod::isPrivate, ReflectionMethod::isProtected, etc. Finally, note that the class ReflectionMethod extends ReflectionFunctionAbstract so be sure to check out the parent class's methods too.

Upvotes: 2

Related Questions