PHPDoc, code completion and iterations with PHP


Coding is very important part within our work as developers. Maybe it isn’t the outcome of our work. Our clients don’t really mind if our code is smart or not. They only want the product or service we give  them. Code is our problem. However smart code and agile programming skills are really useful to accomplish with our objectives. One useful tool is PHPDoc.
PHP is not Java. Java is a strongly typed programming language. Because of that modern IDE helps us a lot when we are coding Java. In PHP we don’t need to declare the type of a variable when we declare it. Even we don’t need t declare the variables. This behaviour can be good or bad. For IDEs it’s very bad. I’m not going to start the first flame-war between Java and PHP now. The fact is that we want to code as fast as we can making less mistakes and writing the less code as we can to reach our goals. PHP has some limitations but we also have some tools as PHPDoc to help us.

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
}
Advertisements

About Gonzalo Ayuso

Web Architect. PHP, Python, Node, Angular, ionic, PostgreSQL, Linux, ... Always learning.

Posted on June 20, 2010, in php, Technology. Bookmark the permalink. 8 Comments.

  1. 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.

  2. Hmm never mind, you actually said that yourself. Just delete my comment, then. 🙂

  3. Thanks… you saved me a bunch of time!
    the /** @var $row MyClass */ approach worked perfectly.

  4. 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
    }

  1. Pingback: Building an ORM with PHP. « Gonzalo Ayuso | Web Architect

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: