Search code examples
phpphpstormphpdoctype-hinting

PhpStorm type hinting for derived class return value


Is it possible to hint PhpStorm that in the code below return value of item() method has the type DOMElement (WITHOUT modifying the actual PHP statements, i.e. by some external setting of PhpStorm or plugin or using PHPDoc comment of some sort, etc.)?

Again, please, don't suggest me to modify the statements in the code, in particular the part $list->item(0)->getAttribute('test').

Also, I found a somewhat similar question PhpStorm type-hinting for factories? but it deals with type-hinting for user-defined functions, in my case the function item() is a predefined library function.

$doc = new DOMDocument();
$doc->loadXML('<x test="123"/>');
$list = $doc->getElementsByTagName('x');
if($list->length > 0)
    var_dump($list->item(0)->getAttribute('test'));

PhpStorm warning


Solution

  • Accordingly to official docs $list->item(0) returns element of DOMNode class which does NOT have getAttribute() method. PhpStorm follows official docs here.

    But if you add extra line into youe code and analyze it in debugger (e.g. $z = $list->item(0);), you will see that $z is instance of DOMElement that has such method.


    A. You cannot add documentation to predefined methods (especially in a chain) on the fly. No way.

    B. As you can see -- the "problem" here is in the docs: they say that item() returns instance of one class while in your particular case it returns instance of different class.


    Few options:

    1. Modify your code to introduce intermediate variable to which you can give correct type hint. As I understand you do not want to use it.

    2. Ignore these warnings: you could disable it completely or for just that file; you could lower the severity (e.g. "info" instead of "warning") etc

    3. Alter documentation (not sure if this is a good idea though).

    This could be done on global level by modifying actual stub file (part of PhpStorm distribution... so it will affect ALL projects and you will have to redo this after upgrading to a newer version again).

    Or you can do this on local level (for this project only):

    • extract stub for DOMNodeList class from original stub file
    • place it in separate file anywhere in your project
    • alter @return tag of item() method -- make it @return DOMElement of whatever you require there.

    This will make IDE "merging" docs from two sources: sort of @return DOMNode|DOMElement.

    Once again -- this will cover your particular case -- how this will affect your other cases I cannot tell.