Keeping Your PHP Code Well Documented

Jacek Barecki

Introduction

Pretty much every PHP developer writes comments along with the actual code. But the language itself doesn’t impose any rules on how to do so. You just have to wrap them around some specific tags and then you can write any content you want. So what exactly should be put in the comment blocks to keep them useful? Which parts of the code should be documented and which shouldn’t? In this article I will present some important rules which may help you in keeping your PHP code well documented and understandable.

1. Write code that explains itself

First and foremost, the code you write may serve as a good piece of documentation even without adding a single comment block to it. While transforming the logic into pieces of code you can do a lot to make the code clear. Here are just a few examples:

Variable, function and class naming
As you can name your pieces of code in almost any way you want, you can use it as your advantage in terms of keeping the code understandable. Just remember to choose clear names, not to make up any strange abbreviations or use names that may be ambiguous. If your variable represents an instance of a VeryImportantCustomer class, just call it $veryImportantCustomer, not $customer, $vimpCust or $tempcustomer. Don’t be afraid of making typos in longer names as your IDE will probably warn you about unused variables or other inconsistencies in your code. I’m sure that using proper naming will help a lot in figuring out what’s going on in your code. It’s a simple rule but it may be easily forgotten in your everyday work.

Type hinting
PHP allows you to put class/interface names or array / callable keywords next to a function parameter. It prevents you from making wrong function calls but it also serves as an important piece of information for anyone reading your code. You don’t have to examine the function body to get to know how to call the function. You can also quickly check how the different functions and classes can pass values between each other. And remember that your IDE will probably interpret the type hints and use them to describe the functions in popups or hints which are being displayed while you’re working.

Method visibility
Another concept worth mentioning is the method visibility. Assigning proper visibility to class methods is said to be an important part of writing quality object-oriented code. On one hand, it shows which code represents the part of the logic that should stay inside the class and shouldn’t be revealed to other classes in the application. On the other, it exposes certain class methods to public access so they can be called from outside the class and communicate with other parts of the application.

If you write code that includes setting proper method visibility, other developers will quickly figure out how to work with the class you’ve developed. They will see that there are a few public methods that they can refer to in their code. They will also notice which parts of the logic that you wrote are left to be handled by private class methods and probably shouldn’t be touched.

Again, such hints are also being interpreted by your IDE. The editor you use can probably show you a list of class methods, along with their visibility. Just look at the image below and notice the lock icons next to the method names:

2. Keep the balance

Of course you may feel that the code itself is not always clear enough and needs additional explanation. It is especially true when you’re implementing a complicated part of the business logic, performing complex calculations or just using commands that are difficult to understand at first sight (like regular expression patterns, array transformations etc.). In such cases writing a short comment will certainly help in getting to know what’s going on.

On the other hand, comment blocks shouldn’t make up for poorly written code. If your code contains too many loops or control structures and even you don’t know how it works without analyzing it for a couple of minutes, leaving it like that with a few comment lines isn’t the best solution. You should rather put some effort in refactoring the code instead of trying to explain it in comments.

Aside from complex code blocks, there are also such parts of code that are clear and do not represent any complicated logic. Some developers tend to put comment blocks even for these parts of their apps, which is unnecessary in my opinion. Let me show you an example:

<?php
    class Deposit {

        /**
         * The deposit owner.
         *
         * @var string
         */
        private $_owner;

         /**
         * The deposit amount.
         *
         * @var float
         */
        private $_amount;

        /**
         * The date when the deposit was opened.
         *
         * @var DateTime
         */
        private $_dateOpened;

        /**
         * Class constructor.
         *
         */
        public function __construct() {
            //...
        }

        /**
         * Sets the deposit owner.
         *
         * @param string $owner The deposit owner name.
         */
        public function setOwner($owner) {
            $this->_owner = $owner;
        }
?>

Remember that the person who reads your code is usually a developer (or at least I suppose so), so he/she will be able to figure out that the _owner property of the Deposit class represents a deposit owner. That’s why I think that putting additional comments to such parts of the code can even make it less readable instead of helping the reader in any way.

Comments are often also unnecessary in other simple parts of your code, not only in class property definitions or typical methods (like constructors, getters or setters). Just see the example below:

<?php

public function showUserDetails() {
    $userId = $this->Session->read('userId');
    $userData = $this->getUserData($userId);
    if(!$user->isActive()) {
        throw new Exception("The user account hasn't been activated.");
    }

    //...
}
?>

I’m sure that you can easily figure out what’s going on in the part of the code presented above. But if you wanted to comment the code, it will probably look like this:

<?php
/**
 * Shows the details of the user that is currently
 * logged in.
 *
 */
public function showUserDetails() {
    //get the current user from session
    $userId = $this->Session->read('userId');   

    //load the user data from database
    $userData = $this->getUserData($userId);

    //check if the user has an active account
    if(!$user->isActive()) {
        throw new Exception("The user account hasn't been activated.");
    }

    //...
}

?>

In fact, the comments added to the method contain almost the same words as those used in the code. Like we previously stated, proper naming makes your code understandable and easy to read. In my opinion, the method shown in the example above doesn’t need any additional comments as everything is described by the code itself. Of course, I still encourage you to write comments in those parts of your app that are more complex and need additional explanation.

3. Remember about the doc blocks

As you can see in the code examples above, some comment blocks contain specific keywords beginning with the @ character. I used @var to describe the type of a class property and @param to inform about the method parameter type. You can also use @return tag which informs about the type of the value being returned by a function. Other tags may be employed to describe some general info about the application or its part (like the author, the package, the type of licence). You can read more about the doc blocks in the Introduction to PhpDoc article written by Moshe Teutsch.

Doc blocks tags contain information that cannot be included in the code itself. Specifying the type of class properties or function return values is especially helpful as it can be parsed by most of the IDEs and shown in hints. Of course you can also insert a custom text in a doc block which will serve as a function or class documentation. It may be especially important if your project needs to have its documentation available from outside the code. In such cases you can make use of the apps that analyze the doc blocks and generate the documentation of the whole application basing on their content. Read Bruno Skvorc’s Generate documentation with ApiGen article to find out more about such an approach.

If the code is easy to understand and I don’t need to produce an extended documentation, I just keep the tags that provide the information about the variable types and return values. In result, the code doesn’t get excessively complicated:

<?php
    class Deposit {

        /**
         * @var string
         */
        private $_owner;

         /**
         * @var float
         */
        private $_amount;

        /**
         * @var DateTime
         */
        private $_dateOpened;

        //...

        /**
         * @param string $owner
         */
        public function setOwner($owner) {
            $this->_owner = $owner;
        }
?>

Summary

In this article I presented some tips on how to maintain the code documentation in a PHP application. I think comments aren’t necessary if you produce code which is clear and just explains itself. The proper place to put comments is when you implement some complex logic or use commands that are just not very readable for a human. It is also worth remembering to insert doc block tags which describe variable types or function return values as such information cannot be included in the code itself. If you need to maintain more detailed project documentation, also put appropriate descriptions in doc blocks.

Feel free to put your comments about the points presented in the article or contact me through Google+. If you have a different opinion or use different rules in your work, tell us about it!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Nguyen Tuan

    good

  • http://RawrLike.Me/ Brandon Stewart

    What IDE do you use when working with PHP?

    • http://dimsav.com/ Dimitrios Savvopoulos

      Looks like phpstorm

      • Jacek Barecki

        Yes, it’s PhpStorm.

  • Stephen Cunliffe

    The one thing I loved about this post was the screenshot… showing all the class methods as “camelCase”. I really wish that the PHP language itself had been (a) consistent with naming, and (b) used camelCase vs. underscore_delimted_names.

    Glad to see I’m far from the only one that doesn’t even attempt to keep the underscores ;-)

  • Taylor Ren

    It is useful, especially when mentioning not to over-comment.

    I agree most on the first point: make the code clear and plain enough to explain itself.

  • Mathieu SAVELLI

    About the “overly-documented” code you speak about in part 2:

    > Remember that the person who reads your code is usually a developer

    I think this is partially wrong (and you stated it yourself in part 3) as the code is often “read” by programs (IDE, Doxygen-likes, etc.) too.
    As these tools are usually here to give your more productivity in your development process, it would be such a loss not to give them a little help to parse the files.

    There are also many code sniffing tools that show tons of warnings when you omit docblocks for variables, class or document.

  • http://www.drlinux.no/ Arne K. Haaje

    >I tend to phpdoc everything… if I come back to code after six
    > months later you get up to speed faster than reading the code
    > itself.

    I’ve found this as well to be the most helpful, also when taking over other peoples code. Also docblocks help the IDE, which can be a real timesaver.

  • Tjorriemorrie

    There are a couple of benefits to documenting the properties of a class. I wholeheartedly disapprove of your opinion.

    • Jacek Barecki

      Thank you for you comment. What kind of benefits do you mean?

  • Janusz Szcząchor

    I am rather a beginner in phping but I agree with you. A code without comments after some time can be very unclear. In my opinion, comments should be very precise but not too short! Sometimes I find them too short so as it is difficult to understand what do they mean.

  • Joseph

    Documenting what DIDN’T work is also important for future development/developers. For instance, getting the name of the next month, by adding one month to the current date, will skip a month and display the name of two months ahead if the date is the 31st. So someone may wonder why the convoluted line to handle this versus what would appear to only need a simple +1 month. Save them time and grief and explain why they should leave it as is!

  • Lyhong Pon

    Where should I place comment for if else and else?