Writing Drupal documentation with PHPDoc

Chris's picture
Comments (4)
Post a new comment
Chris
12 January, 2012 - 17:24

Documenting your Drupal code using PHPDoc is part of building any kind of Drupal site that involves writing code, whether you're writing a mega-module like views, or just writing a quick front-end theme. This quick reference guide will get you going, or act as a simple refresher if you haven't done it for a while.

Why document?

To put it really simply, your code is not finished unless it is documented. Documentation helps other people understand your code, it helps you understand your own code once you've come back to it after 6 months, and it even helps you write better code, making you think about what you're writing. PHPDoc comments, in particular, which live at the beginning of funcitons, can automate the process of building the API for your code (this is what api.drupal.org uses).

However, I'm going to make the assumption you already want to document your code, otherwise you wouldn't have read this far, right?

What do I document?

Everything. No, seriously. Every function, class and method. If there is a function in your code that has no PHPDoc comment at the top, you should go back and write documentation for it.

When should I document?

As you're writing the code. If you write the code, and then go back to document it, the chances are you'll either give up because you can't be bothered, or your documentation will be worse because you won't remember as clearly what each individual function does. A good IDE (integrated development environment) will generate PHPDoc stubs, so you write the function signature (the line that starts "function" and has all the parameters) and the IDE will generate a blank PHPDoc block in the correct format. See our guide to setting up JetBrains PhpStorm if you want a recommendation on a solid IDE.

What if it's just a hook?

You don't need to fully explain what the hook does, but you still need to document it. Just write what hook you're implementing. The reader will then know to look in the API to find the definition for the hook. See Doxygen and comment formatting conventions for more.

  1. /**
  2.  * Implements hook_menu().
  3.  */

What if it's form API stuff?

You can just document it like this:

  1. /**
  2.  * Submission handler for mymodule_form().
  3.  */
  4. function mymodule_form_submit($form, &$form_state) {
  5.   // code here
  6. }
  7.  
  8. /**
  9.  * Validation handler for mymodule_form().
  10.  */
  11. function mymodule_form_validate($form, &$form_state) {
  12.   // code here
  13. }

The function should be summarised on the first line

The first line of your PHPDoc block should contain a summary of the function's purpose.:

  1. /**
  2.  * Retrieves a complete foo from the database.
  3.  */

If you want to explain it in more detail, that's great. No, really, that's super that you want to write more than a single line! Do it! Leave a completely blank line between your summary and the rest of the PHPDoc block.

  1. /**
  2.  * Retrieves a complete foo from the database.
  3.  *
  4.  * Will check to make sure that the foo's bar is correct before
  5.  * attempting to do anything, and calculates the baz ratio
  6.  * internally as it goes.
  7.  */

Always document the return value

Some functions don't return anything. That's fine, just say it returns void. Otherwise, give the type that it returns, and give a description of what the caller can expect to get out of the function:

  1. /**
  2.  * Retrieves a complete foo from the database.
  3.  *
  4.  * @return string
  5.  *   The text describing the foo.
  6.  */

Note that the text describing what the function returns is indented by 2 spaces from the @return, and if it goes onto multiple lines, indent those too.

The comment block should never go beyond 80 characters in line length. All IDEs and most text editors can show you an 80-column "margin" or "print margin" which will let you know where to wrap comment lines.

Documenting parameters

You need to document every single parameter that gets passed into your function. You should use @param type $name (the type should come before the parameter name). Don't leave the type out! It helps massively in understanding what to give to the function.

  1. /**
  2.  * Retrieves a complete foo from the database.
  3.  *
  4.  * @param int $foo_id
  5.  *   The numeric ID of the foo to be retrieved.
  6.  *
  7.  * @return string
  8.  *   The text describing the foo.
  9.  */
  10. function mymodule_retrieve_foo($foo_id) {
  11.   // code here
  12. }

Note how, in the example above, there is a blank line between the parameter listing and the return value.

For parameters that can accept more than one type, you can always write:

  1. /**
  2.  * Retrieves a complete foo from the database.
  3.  *
  4.  * @param int|string $foo
  5.  *   The numeric ID or the machine-readable name of the foo to be retrieved.
  6.  *
  7.  * @return string
  8.  *   The text describing the foo.
  9.  */
  10. function mymodule_retrieve_foo($foo) {
  11.   // code here
  12. }

There are times when the parameter might be able to take so many types that you might want to write:

  1. /**
  2.  * Retrieves a complete foo from the database.
  3.  *
  4.  * @param mixed $foo
  5.  *   The numeric ID, machine-readable name, or array representation
  6.  *   of the foo to be retrieved.
  7.  *
  8.  * @return string
  9.  *   The text describing the foo.
  10.  */
  11. function mymodule_retrieve_foo($foo_id) {
  12.   // code here
  13. }

Documenting arrays as parameters or return values

If the parameter or return value is an array, it's not enough to just declare that it's an array, you need to explain what keys are expected in the array, and what values they can have. Don't worry if your PHPDoc blocks are long. You're using a proper IDE, not Dreamweaver or notepad, right? So you have a function list and you can quickly jump to the definition of any function within your code? Of course you can, so you needn't worry about scrolling through loads of PHPDoc.

  1. /**
  2.  * Retrieves a complete foo from the database.
  3.  *
  4.  * @param int $foo_id
  5.  *   The numeric ID of the foo to be retrieved.
  6.  *
  7.  * @return array
  8.  *   An array representing the foo, with these keys:
  9.  *   - id: the numeric ID of the foo.
  10.  *   - name: the machine-readable name of the foo.
  11.  *   - created: a UNIX timestamp representing the foo's creation date and time.
  12.  */
  13. function mymodule_retrieve_foo($foo_id) {
  14.   // code here
  15. }

What your documentation should say

Don't explain how PHP or Drupal works. Expect that the reader already knows this information. Explain, in human terms, what the code does, and highlight any unexpected behaviour. The reader should be able to understand how to call the function, what it does, and what it will give back, without having to read the code. The code is there, of course, but the element of human error can be reduced by properly documenting things.

A (more or less) complete example

  1. /**
  2.  * Retrieves a complete foo from the database.
  3.  *
  4.  * Will check to make sure that the foo's bar is correct before
  5.  * attempting to do anything, and calculates the baz ratio
  6.  * internally as it goes.
  7.  *
  8.  * @param int $foo_id
  9.  *   The numeric ID of the foo to be retrieved.
  10.  * @param array $options
  11.  *   An array of extra information used to retrieve the foo, with keys like this:
  12.  *   - color: a string representing the hex colour code for the foo.
  13.  *   - bar: a string representing the type of bar to be returned with the foo.
  14.  *   - html: TRUE or FALSE. Determines whether to return the foo as HTML or not.
  15.  *
  16.  * @return string
  17.  *   The foo represented as a string, surrounded by HTML if that option was provided.
  18.  */
  19. function mymodule_retrieve_foo($foo_id, $foo_type) {
  20.   // code here
  21. }

Your comments

I intend this to serve as a handy reference guide for anyone who quickly needs to see examples that aren't covered by the coding standards document, so do let me know about any corrections, or any additions you might like to see.
4

Comments

Jamil Daglees's picture
Jamil Daglees15 January, 2012 - 08:18

This looks great, well structured and written.

I'm currently using NetBeans and it has PHPDoc support.

NCLEX PREP's picture
NCLEX PREP27 February, 2012 - 05:38

Great pleasure to visit your blog. I love to read interesting post that has knowledge to impart! I've learn so much from this. Thank you for sharing.

pozycjonowanie bielsko's picture
pozycjonowanie ...1 March, 2012 - 17:24

Thanks, well structured and written

carlos's picture
carlos27 October, 2012 - 13:38

really well explained. thanks for this. will help me with my first big drupal project.

Add new comment