PhpDoc for interface and class implementing interface - difference

Marcin Nabiałek picture Marcin Nabiałek · Jul 30, 2014 · Viewed 9.2k times · Source

The question is quite simple - how should I differ phpdoc for interface and for class implementing interface? Should/Can they be the same or maybe interface documentation should be as general as possible and class implementing this interface more specific?

I include one method phpDoc from my real code:

My interface:

interface CacheInterface 
{
    /**
     * Adds data to cache
     *
     * @param string $objectId    Name of object to store in cache
     * @param mixed  $objectValue Data to store in cache
     * @param mixed  $lifetime    Lifetime of cache file
     * @param string $group       Name of cache group.
     * @param array  $params      Parameters that distinct cache files.
     * @param array  $files       Name of files that are checked if cache is valid.
     * @return bool               True if cache was created, false if cache was not created
     */
    public function put(
        $objectId,
        $objectValue,
        $lifetime = null,
        $group = null,
        $params = array(),
        $files = array()
    );
}

My class implementing interface:

class Cache implements CacheInterface
{
    /**
     * Adds data to cache
     *
     * @param string $objectId    Name of object. If it begins with : cache filename will be created using hash
     *                            function. If name doesn't begin with : it should use ASCII characters to avoid
     *                            problems with filenames
     * @param mixed  $objectValue Data to store in cache
     * @param mixed  $lifetime    Lifetime of cache file. If none provided it will use the one set in contructor.
     *                            Possible lifetime values: time in seconds (3600 means that cache is valid
     *                            for 1 hour = 3600 seconds) or one of TIME_ constants @see CacheInterface
     * @param string $group       Name of cache group. If none/null provided it will use the one set in constructor.
     *                            Sub-groups should be created using | for example group|subgroup|subgroup2
     * @param array  $params      Parameters that distinct cache files. You can for example pass here array('id' => 1)
     *                            to set cache for user id. If $params is not empty, they are also used to generate
     *                            file name. That's way they should rather include simple ASCII values
     * @param array  $files       Name of files that are checked if cache is valid. It should be numerical array
     *                            (not assosiative). If files are not empty when getting data from cache it's checked
     *                            wheteher those files exists and are created earlier than cache was created.
     *                            If any of those conditions is not met cache file is treated as invalid
     * @return bool               True if cache was created, false if cache was not created
     */
    public function put(
        $objectId,
        $objectValue,
        $lifetime = null,
        $group = null,
        $params = array(),
        $files = array()
    ) {
       // implementation here
    }
}

Is that the way documentation should look like? More general for interface and more specific for class implementing this interface?

Answer

ashnazg picture ashnazg · Jul 30, 2014

The direct answer to your direct question is "yes". The more general descriptions on the interface are good, and you should only augment that info in the class descriptions. I would choose to not duplicate the tags on the class methods, because by doing so, you prevent your interface's information from being seen... you're effectively overriding it. I realize the working problem here is that not all IDE autocompletions and info popups correctly handle such inheritance analysis correctly (or at all).

As a longtime phpDocumentor and IDE user, my best practice is to actually only document the interface. When it comes to docblocks for the classes that implement the interface, the only info I'd include there is the @internal tag to write developer-specific info that should not appear on the interface API docs. I expect my IDE to know that the class's implementing method should pull its docs from the interface's docblock.

Usage of {@inheritdoc} in the wild is inconsistent on what it really intends to accomplish, and I think bugs in phpDocumentor 1.x's handling of that tag over time caused people to try different ways of using it, which then resulted in IDEs also treating it differently. As a result, it's no longer a practice I use at all.