PhpDocumentor 'not a PHP file' issues

How do I get phpdocumentor to read php command-line scripts and other files that don't use the .php and .inc file name extensions?

Note: This text refers to version 1.4.3 of PhpDocumentor.

In most cases the problem is simply that PhpDocumentor will check the file name extension against a list which is in the PhpDocumentor.ini file. The default list of known extensions is fairly short so it's likely that many programmers will want to add to it.

On ubuntu systems you can change the list of file extensions by editing the PhpDocumentor.ini file here:

/usr/share/php/data/PhpDocumentor/phpDocumentor.ini

The text you want to edit is in a group called _phpDocumentor_phpfile_exts:

[_phpDocumentor_phpfile_exts]
php
php3
php4
phtml
inc

Simply add whatever file extensions you want to use.

A much bigger problem exists if you want to document command line scripts that you have written in PHP. In this case it becomes necessary to change the PhpDocumentor code.

The function that must be edited is readPhpFile($path, $quietMode = false) in Io.inc. On ubuntu systems you can find it here:

/usr/share/php/PhpDocumentor/phpDocumentor/Io.inc

The block of code that must be changed is near the top:


$ext = $_phpDocumentor_phpfile_exts;
if (file_exists($path))
{
    if (is_file($path))
    {
        // check extension
        $tmp = explode(".",$path);
        // tiberiusblue addition
        $tmp2 = $tmp;
        if (in_array(array_pop($tmp),$ext))
        {
            phpDocumentor_out(" -- Parsing file\n");
            flush();

Note that the code assumes that there is a dot in the file name - but your server maintenance scripts probably don't have one. Ideally what we want is to not have to write any code at all as it's been written before. The file program, a standard unix utility, will search the first few bytes of any file and return a terse description of that file. Ideally we can just let the file program tell us if the file is a PHP file or not. Of course, if it doesn't know, the existing PhpDocumentor code can take over.

My solution is below. Don't just copy it - you will need to check your system to ensure that you have the file utility and that it's located in /usr/bin.


$ext = $_phpDocumentor_phpfile_exts;
if (file_exists($path))
{
    if (is_file($path))
    {
        // TODO: replace the file name with a configurable constant
        if ( file_exists( "/usr/bin/file" ) )
        {
           $desc = `/usr/bin/file "{$path}"`;
           if ( strpos( strtolower($desc), "php" ) !== false )
           {
              phpDocumentor_out(" -- Parsing file\n");
              flush();
              if (function_exists('file_get_contents')) {
                 return file_get_contents($path);
              }
              $fp = fopen($path,"r");
              $ret = fread($fp,filesize($path));
              fclose($fp);
              return $ret;
           }
        }
        // check extension
        $tmp = explode(".",$path);

Note also that the test for the "php" string might be too simple in some cases. It's entirely reasonable in my case but you might find some cases where PhpDocumentor is scanning files that are not php files. In that case you will want to make a list of valid descriptions returned by the file utility and check for them more carefully.

Unfortunately the above, while it does work, is not enough. PhpDocumentor will continue to emit a note saying that it is ignoring any script files that have been specified in the configuration file. It turns out that this decision is made by a function called checkIgnore(). The source for this function just happens to be a little further down in Io.inc.

checkIgnore() is called in a few places by Setup.inc.php. The function has the option to detect file names that don't have an extension. For some reason, though, there is no corresponding option in the PhpDocumentor.ini file. The calls to checkIgnore() from Setup.inc.php all pass a boolean constant to force all file names without extensions to be ignored.

The proper solution to this problem would be to add code to change the hard-coded booleans into configuration options. It wouldn't be difficult as all the bits and pieces necessary are pretty much in place already. On the other hand it's also possible to hack a quick fix by just setting the function parameter to false like this:


function checkIgnore( $file, $path, $ignore, 
                      $ignore_no_ext = true, 
                      $ignoresymlinks = false )
{
    global $_phpDocumentor_RIC_files;

    // TODO: change this to a configuration option
    $ignore_no_ext = false;

This is not pretty but it works for now.

Once the three changes above are made (add your file extensions to the global ini file and make the two edits to the Io.inc script,) it becomes possible to use PhpDocumentor to document any php script without file name restrictions.