Search code examples
phpphpstormphpdoc

How to tell phpDoc a string is a class name?


I often give objects static methods and properties that do not require the object to be initialized. For example:

class SomeObject {
    public function __construct($object_id) {
        $this->loadProperties($object_id);
    }

    public static function getSomeStaticString() {
        return "some static string";
    }
}

Now we subclass these objects and have some sort of controller that returns an object class string under certain circumstances where the object should not yet be initialized. For example:

class SomeObjectController {
    public function getSomeObjectWithTheseProperties(array $properties) {
        if($properties[0] === "somevalue") {
            if($properties[1] === "someothervalue") {
                return SomeSubclassObject::class;
            }

            return SomeObject::class;
        }

        return NULL;
    }
}

At times I might want to call the static function SomeObject::getSomeStaticString() without actually initializing the object (because that would involve an unneeded database fetch). For instance:

$controller = new SomeObjectController;
$properties = array("somevalue", "someothervalue");
$object_class = $controller->getSomeObjectWithTheseProperties($properties);

echo $object_class::getSomeStaticString();

Question: can I somehow tell PhpStorm, preferably through phpDoc, that $object_class is a class string of a subclass of SomeObject?

If I tell my IDE it's a string, it will notify me getSomeStaticString() is an invalid method. On the other hand, if I tell my IDE it's an instance of SomeObject, it thinks I can access regular non-static methods and properties, which I can't.


Solution

  • PHPStan uses the class-string PHPDoc type for this. It has been supported by PHPStorm since 2020.3, but it seems to work properly (with all autocompletion available) as of 2021.2, when they added support for Generics.

    In your case the return type annotation would be @return class-string<SomeObject>.