picture of Stefano Locati
So you've read about how Object Oriented programming can help you with your big web projects and you've started it using with PHP? If you've already written a handful of classes to implement a site and you're methodic, then you should have written some documentation about them. But If you're just messy like me you've just written some comments within the classes' source and no other documentation. Without documentation it's difficult to remember methods' names and the way they have to be used (parameters and meaning). The typical way to solve this situation is to have source code files open and to skim through hundreds or thousands of lines.

Javadoc Like Documentation

There must be a better way -- if you are used to the Java language you will know the Javadoc documentation system. This tool allows you to insert tags within comments of your source files that are then parsed by Javadoc tools in order to generate a set of HTML pages documenting your classes. So while you program you can keep your browser open and you'll have a list of your classes and methods with descriptions. This will become your reference to be more productive and fast while building your web application.
In my opinion maintaining a documentation as a reference within source code is easier and more practical than having to do it in a separated document because in this way it's easier to keep it updated. Otherwise it's very easy to become lazy and postpone updates in the documentation to a time that never comes. Instead with a tool like this there is the little burden to update a tag near the source code you've just modified and to run the tool to generate again the updated html pages.

Overview of Some Php Documentation Tools

Having all of this on mind I have been looking for what was available and I have discovered some interesting tools like the following ones:
phpSearchdoc is a component of the enzyme project. Since enzyme is a big project there was the need of documenting it. Their developers have been writing their own documentation system and they have been kind enough to release it also as an independent package. The documentation gets first written into a database and then it can be viewed with some PHP scripts as a dynamic web site.
The idea to separate parsing logic from presentation is indeed good, however phpSearchdoc (version 1.01) doesn't have a real parser but looks for keywords anywhere in the source, even within comments. In fact, it really have happened to me to have the word 'function' within my comments, and yes, the parser got fooled by thinking that the words following this word were the function's name. Unfortunately then, I was unlucky to have an apostrophe (') in the same line, and when I was trying to write data into the database, mysql has complained (the apostrophe is used to delimit strings in mysql).
Furthermore it's really difficoult to set up and get it working since it's still in alpha state. And after all it's more a cross reference generator than a documentation system because, as far as I know, you can't add your own comments to functions or methods.
phpxref, as the name suggests seems to be more oriented to the generation of a cross reference than a real documentation. Further it seems to be suited more for a regular procedural programming rather than for object oriented programming.
phpautodoc aims to be for PHP what Javadoc is for Java. It seemed to be the perfect solution for my documentation needs. To try it out I had to compile the CGI version of PHP (I normally use the module version), because the generator is written in PHP. I could compile and install the static executable on a Linux system easily with these commands:
rm config.cache
make clean
./configure
make
cp php /usr/local/bin
I decided to test this script on its own PHP source and I found it working partially: it could just generate the documentation of the classes (neatly formatted), but not the summaries. I don't know if this happens just on my machine, but it just stopped with a core dump (PHP 4.0 pl2 on a RedHat 6.2) when trying to generate the summaries. Supposing you've a PHP executable installed in /usr/local/bin the syntax for calling it is (to have some results I had to give full paths of both the php files and the output directory)
./phpautodoc <php_files> -o <output_dir>
phpdoc is a tool to maintain documentation about PHP files on the web and it is best suited for distributed development efforts. The documentation gets written into a MySQL database; after installing it you can document your classes by adding them using a web interface. This is really interesting but is a way to maintain a low level documentation separatated from source code which as I said it's not very convenient.

A General Purpose Tool

After experiencing some frustration trying all these tools without much success and until a standard solution is proposed by the Pear Project, I found a working tool completely unrelated to PHP in the Open Source Projects at Apple website. The name of the project is HeaderDoc. As the website states HeaderDoc is a tool for generating HTML reference documentation for comments of C or C++ header files. It is written in Perl for easy portability. Similar to JavaDoc, it allows developers to easily document their interfaces and export that information into HTML.
Yes, you've read well, HeaderDoc supports just C and C++. No other languages, but it happens that, unlike Javadoc, it relies mostly on tags written inside comments and so can works well for PHP too with minor modifications (I will explain later). The tags are Javadoc-like, some examples of Headerdoc tags are @class, @function and @var.

Documenting A Class

Ok so let's dive into details now. First let's take a look to how a class can be documented.
/*! @class BagItem
    @abstract An item in the shopping bag - it is a shopitem with quantity
    @discussion A BagItem object may be constructed without previous instantiation 
	of neither ShopItem nor Product
*/
Documentation of a class
Documentation of a class. On the left frame it is possible to choose a method of the class.
The first thing to notice is that the style used to open comments is not exactly like Javadoc comments /** (a slash and two asterisks), but is instead /*! (a slash, an asterisk and an exclamation mark). Tags are different too, but they work in a similar way. For example the first tag is the @class tag which is used to document a class, this tag is followed by the class name. The next tag is the @abstract tag which is an optional tag describing in a few words the meaning of the class, while the @discussion tag is another optional tag used for a more in depth discussion. Of course it's up to you to decide wether to write everything in the @discussion tag or use the @abstract too, but remember that in general, the more specific tags you use, the better the results are.

Documenting Functions or Methods

Member functions or methods are documented with the @function tag.
/*! @function getItemingroup
    @abstract gets a bagitem of a given group and a given position 
    @param groupno int - the delivery group ordinal position in the bag
    @param pos     int - the position of the bagitem within the group 
    @result Object - the BagItem in a given position of given group
	or -1 if it could not be found
 */
Documentation of a Method
Documentation of a method.
A @function tag declares a function and is followed by a function or a member function name. Then you can use @abstract and @discussion tags like before. There are however two additional tags. The @param tag is used to describe function's parameters; the first word is assumed to be the variable name, while the rest is a free text description. I suggest to state the expected type of the variable, even if PHP is not a strong typed language. The @result tag is used to describe the return value.

Documenting Variables

Variables or class variables are described with the @var tag. Within this tag, the first word is assumed to be the variable's name, while the rest is free text description. Like before I suggest that writing the expected type of the variable is good. It's also a good idea to document all your class variables.

documentation of a class variable

Documentation of a class variable.
/*! @var idsession   string - an unique session identifier */
var $idsession;

A Final Touch

/*! @header myprojectname
    @abstract a virtual store to shop on mars
    @discussion The difference [...]
 */
The @header tag is used to provide some general info about the project or the group of classes being documented. The @header tag itself is followed by the project name and is useful to complement it with @abstract and @discussion tags. Since classes are generally in different files (and it is usually a good idea to have one file per class named after the class name), you might wonder where you should place the @header tag. The answer is, surprisingly enough, anywhere. I suggest to place it in a separate file if it's a long discussion or on the top of the most important class if it's a shorter comment.

How To Modify The Script For PHP

The original HeaderDoc script from Apple is meant for C or C++ headers, so it has to be slightly modified to use it with PHP. If you're not interested about details you can just download it and skip to the next section.
The only thing to modify in the sources is in the main perl file and it's made to make the script accept .php and .php3 extensions.
$ diff headerDoc2HTML.pl /usr/local/bin/headerdoc2html
195c195
<     ($rootFileName = $filename) =~ s/\.(h|i)$//;
---
>     ($rootFileName = $filename) =~ s/\.(h|i|php|php3)$//;

Running The Script

After having installed the script, supposing that your classes are in the classes subdirectory and that you want to put the generated documentation in the docs directory, you should issue this command:
headerdoc2html -o docs classes/*.php
Unfortunately if there are multiple PHP files, this script has the bad habit to split those files in different directories, making navigation among classes' documentation more difficoult. Moreover since the original script was written for C/C++ header files that are just declarations of classes and functions and have no definitions for them, it outputs all the code following the function name until a ; is found, so tipically the first line of code.
But before you get desperate after all the effort reading till now, relax because I wrote a simple script to solve both these problems.
cat classes/*.php | sed 's/ *{/;#{/g' | tr "#" "\n" > docs/all.php
headerdoc2html -o docs docs/all.php
rm docs/all.php
If you're wondering why I use the tr utility here instead of doing all the job with sed, the reason is that sed 3.02 that is still used on RedHat 6.2 doesn't handle newlines. The new version sed 3.02a would be needed instead. If you're curious see the SED FAQ.
Good luck with your documentation effort!
Stefano Locati
--Stefano