Let’s start with an example
class MyClass { function hello($name) { return "Hello " . $name . "\n"; } }
When we want to use this class and we type:
$obj = new MyClass; echo $obj-> <------ code completion appear in our IDE suggesting hello function
But now we put a simple singleton function in MyClass
class MyClass { private static $_instance = null; function singleton() { if (is_null(self::$_instance)) { self::$_instance = new self; } return self::$_instance; } function hello($name) { return "Hello " . $name . "\n"; } }
And we use our singleton:
echo MyClass::singleton()-> <---- ups nothing happens
That’s because our IDE doesn’t know the return type of our singleton function. Because of that we are going to help to our IDE with a bit of PHPDoc magic.
private static $_instance = null; /** * @return MyClass */ function singleton() { if (is_null(self::$_instance)) { self::$_instance = new self; } return self::$_instance; }
And now our IDE will help us.
And now something a bit different. We have other class:
class MyClass2 { static function getAll() { return array(new MyClass, new MyClass, new MyClass); } }
According to PHPDoc manual we can hint getAll function with @return array[int]MyClass but code completion doesn’t work, at least on my tests (please tell me I’m wrong because it’s the best solution).
So I need to use a small trick to get the autocompletion:
foreach (MyClass2::getAll() as $row) { /* @var $row MyClass */ echo $row-> <------------------- code completion appear }
I’ve tried with @return array[int]MyClass and also using SPL Iterators but that’s the only way I know to ensure autocompletion.
Other possible solution is use a dummy cast function in MyClass. It’s a bit ugly solution but also works always:
/** * @param MyClass $cls * @return MyClass */ static function cast($cls) { return $cls; }
Now We can use:
foreach (MyClass2::getAll() as $row) { echo MyClass::cast($row)->hello("Gonzalo"); // code completion works }
Nice Code
A rather late reply, but you should be able to skip the MyClass::cast() thing, by doing something like this:
foreach (MyClass2::getAll() as $row) {
/** @var $row MyClass */
echo $row->hello(‘world’);
}
Now, instead of having to call MyClass::cast() N times, PHP just needs to throw away a comment line once.
Hmm never mind, you actually said that yourself. Just delete my comment, then. 🙂
Thanks… you saved me a bunch of time!
the /** @var $row MyClass */ approach worked perfectly.
good to hear it 😉
Note that you can also can set the return parameter as an array of specific classes, example:
class MyClass2
{
/**
* @return MyClass[]
*/
static function getAll()
{
return array(new MyClass, new MyClass, new MyClass);
}
}
By adding the “[]” after the return line, you specify that the result is an array of MyClass instances.
Your IDE will automatically use code completion in a foreach loop now for the objects.
foreach (MyClass2::getAll() as $row) {
echo $row-> <————- Code completion will apear without using the @var line
}
Checked. Cool! It works like a charm with PHPStorm,