March 29, 2012

A tip for using Doxygen for PHP code

In the last few days I've spent some time researching for a documentation tool for my PHP sources, and after running a couple of circles, I've ended up using Doxygen.
It had some issues though, especially referring to namespaces in the docblock comments, because the docblock syntax allows using backslashes for commands, e.g. \param instead of @param.
I really don't understand why PHP's developers decided to use backslashes as separators for namespaces, but that's a different story.
So, if you use namespaces in docblock comments, you have to escape backslashes, but I didn't want to do that in my code, so I've created an input filter for Doxygen in PHP which does that for me.
It also appends variable names to @var type declarations, so e.g.
/**
 * @var string
 */
public $name;

becomes
/**
 * @var string $name
 */
public $name;

which would be redundant in your code, but Doxygen seems to prefer this format.

I've added the filter to a Bitbucket repository, find it here:
https://bitbucket.org/tamasimrei/misc-tools/src/master/doxygen/filter.php

Licensed under the MIT License.

See the Doxygen documentation on how to use an input filter, but basically it's just adding a line like this to your Doxyfile config file:
INPUT_FILTER = /home/tom/misc-tools/doxygen/filter.php

Comments are welcome.

7 comments:

  1. Hi,

    Nice filter. I tried it, and there's a couple of things I'd like to ask if you could implement to improve it.

    Let's take the following code as the example:

    /**
    * The title of the dialog. Only used it not empty.
    * @var string
    */
    public $title;


    1) If you try the filter at http://stackoverflow.com/questions/4325224/doxygen-how-to-describe-class-member-variables-in-php/8472180#8472180 , you'll see that in the "Public Attributes" list in the generated docs for a class, this will add the data type before the attribute name. I did not get the same behavior with your filter, and I think it's useful to see the data type in the attribute list (and not just in the full attribute details further down on the page).

    2) Something I haven't seen in either of these filters is getting the first sentence in a @var's descriptive text to show up in the "Public Attributes" list for a class. I think it should say this:

    string $title The title of the dialog.

    But instead I'm only getting this with Doxygen:

    $title

    If I apply that other filter I linked to, I get:

    string $title

    Doxygen is tricky to get perfect stuff out of with PHP code :)

    ReplyDelete
  2. Thanks for the comment.
    I would recommend to update Doxygen to the latest version.
    Using 1.8.0, generates exactly what you're describing:

    Source: http://bayimg.com/eApcIaAdC
    Class reference: http://bayimg.com/EAPCkaaDc
    Field documentation: http://bayimg.com/eapClaaDc

    * sorry for the images, this source and documentation is not open source, yet :)

    ReplyDelete
  3. Hi,

    Thanks for responding :)

    I found that setting JAVADOC_AUTOBRIEF to YES made Doxygen grab that first sentence in the inline doc and show it with the properties (when it is showing anything at all for them).

    The other thing is very odd though. I am running Doxygen 1.8.1.1 from the "official" OS X application package. But it refuses to see the documentation for my properties. For example:

    /**
    * Content of the error dialog.
    *
    * @var string
    */
    public static $errorDialogContent = 'foo';

    .. results in only http://grab.by/ealk . I have been through the entire Doxygen config file now, but the only way I've found that make it at least create a link for these is to turn on the EXTRACT_ALL. This does not make it see the actual documentation though, it only creates "empty" entries as in http://grab.by/ealq and http://grab.by/eat0 .

    I also see the following error message in the processing output:

    AjaxProcessingWidget.php:27: warning: documented function `AjaxProcessingWidget::string' was not declared or defined.

    It seems to suggest that the "@var string" it found was interpreted as a function instead of an attribute/property documentation. It simply isn't getting the fact that this is documentation for the following property.

    Turning the "@var string" into "@var string $errorDialogContent" in the source code resolves it, see http://grab.by/eatG and http://grab.by/eatI .

    Could you possibly tell me if you did anything else than install Doxygen, generate a Doxyfile, edit that, and then run the stuff? I'm beginning to wonder if there's something fundamental I'm missing. Maybe you could also show the changed settings in your Doxyfile? :O

    Here are the changes I have made to my Doxyfile (from the default one):

    PROJECT_NAME = "Foo"
    ALWAYS_DETAILED_SEC = YES
    JAVADOC_AUTOBRIEF = YES
    TAB_SIZE = 4
    ## Reverting the following to the default of NO makes no difference:
    OPTIMIZE_OUTPUT_JAVA = YES
    EXTENSION_MAPPING = php=PHP
    INPUT = ../trunk/protected/components
    FILE_PATTERNS = *.php
    RECURSIVE = YES
    SOURCE_BROWSER = YES
    REFERENCED_BY_RELATION = YES
    REFERENCES_RELATION = YES
    HTML_COLORSTYLE_HUE = 220
    HTML_COLORSTYLE_SAT = 170
    HTML_COLORSTYLE_GAMMA = 70
    GENERATE_TREEVIEW = YES
    GENERATE_LATEX = NO
    HIDE_UNDOC_RELATIONS = NO

    Thanks a lot!

    Regards, Leo

    ReplyDelete
  4. One thing I've noticed that you don't have the INPUT_FILTER in the Doxyfile settings list you've included.

    Here are my changes to the default Doxyfile (only those which may be related to the issue):

    JAVADOC_AUTOBRIEF = YES
    OPTIMIZE_OUTPUT_FOR_C = YES
    EXTRACT_ALL = YES
    EXTRACT_PRIVATE = YES
    EXTRACT_STATIC = YES
    EXTRACT_LOCAL_METHODS = YES
    HIDE_SCOPE_NAMES = YES
    INPUT_FILTER = /..../tools/doxygen/filter.php

    I used doxywizard to generate the first version, then customized it.

    ReplyDelete
  5. Okay, but if you remove your filter, does your Doxygen then still generate the public attribute list with data type info and a brief description in them?

    ReplyDelete
  6. This is what it looks like without the filter: http://i.imgur.com/NsXBR.png
    Which explains why I created it :)

    ReplyDelete
  7. I must have misunderstood something here, one way or the other. But we can conclude that without a filter, Doxygen does not understand/see "@var string" correctly. Good to know!

    Thanks for trying to work this out!

    ReplyDelete