Question

I have code more or less like this:

class Foo {
    public static function factory($str) {
        $class = "Foo_" . $str;
        return new $class;
    }
}
class Foo_Bar {
    public function razzle() {
        print "Foo_Bar->baz() was called";
    }
}

$Obj = Foo::factory('Bar');

and I would like PhpStorm to understand that $Obj is a Foo_Bar object, so that for example if I type $Obj->raz, razzle() will show up for autocompletion.

Is there any way to get this? To tell PhpStorm that the function Foo::factory($str) returns an object of type Foo_$str? My guess is that the answer is no.

Was it helpful?

Solution 2

Yes, you can do this if your factory is a static method. It should work fine for the examples you have provided.

More details and some basic example can be found here: http://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata

OTHER TIPS

As far as I know you can't make PHPStorm understand what Foo is giving out, because it is dynamic. However you can surely tell PHPStorm what your $Obj variable is, by putting a doc comment above it, like so:

/** @var Foo_Bar $Obj */
$Obj = Foo::factory('Bar');

You should use phpstorm metadata, that works for both dynamic and static calls.

class Foo {
    public function factory($str) {
        $class = "Foo_" . $str;
        return new $class();
    }
}
class Foo_Bar {
    public function baz() {
        print "Foo_Bar->baz() was called";
    }
}

$Obj = Foo->factory('Bar');
$Obj->baz();  

create a file in your project root directory and name it .phpstorm.meta.php:

<?php

namespace PHPSTORM_META {
    $STATIC_METHOD_TYPES = [
        \Foo::factory('') => [
            "Bar" instanceof \Foo_Bar,
        ],
    ];
}

thanks @LazyOne for link.

One way which worked for me is to explicitly list in an "or" list all of the possible classes the factory might spit out.

/**
 * @param $str
 * @return Foo_Bar | Foo_Cad | Foo_Dad
 */
class Foo {
    public static function factory($str) {
        $class = "Foo_" . $str;
        return new $class;
    }
}

But this does mean all the method type hinting on the instance/object will have the union of all of the listed classes.

Not perfect, but still better than nothing, and still better than having to write /* @var ClassA */ multiple times on every instance it occurs.

One way is to explicitly list in an "or" list all of the possible classes the factory might spit out.

<!-- language: lang-php -->

/**
 * @param $str
 * @return Foo_Bar | Foo_Baz | Foo_Cad
 */
class Foo {
    public static function factory($str) {
        $class = "Foo_" . $str;
        return new $class;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top