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,