Open-source project
phpDocumentor/phpDocumentor avatar
phpDocumentor/phpDocumentor

phpDocumentor: generating PHP API docs from docblocks

Documentation Generator for PHP

4,346 stars648 forksPHPMIT

At a glance

What is it?
phpDocumentor reads your PHP source and DocBlock comments and writes a browsable API reference. It is a mature tool with a two-step pipeline, a Composer install the maintainers discourage, and class diagrams that need PlantUML.
Who is it for?
Adopt phpDocumentor if you maintain a PHP library or framework whose public API needs a browsable reference and you already write DocBlocks. Skip it if your code is undocumented and you expect the generator to fill the gap, if you need class diagrams but cannot install PlantUML, or if Composer is your only allowed install channel.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What phpDocumentor is for, and the projects it fits

phpDocumentor is a documentation generator for PHP. It reads your source files together with the DocBlock comments above classes, methods, properties and functions, and writes a set of API documentation pages. The README describes it as the de-facto documentation tool for PHP projects, which is a claim about adoption rather than a technical property. The useful part is the input contract: the tool's output quality is bounded by the DocBlocks you already wrote. If your code has no comments, phpDocumentor will still produce a structural index of classes and methods, but the prose pages will be thin.

The audience is narrower than "PHP developers". It fits library and framework maintainers who publish an API other people consume, and who want that reference regenerated as part of a build. It also fits teams that keep a written manual in RestructuredText or Markdown and want parts of the API reference embedded in it, so the manual and the code do not drift apart. It does not fit application code where the only reader is the team that wrote it. Generating a site for internal controllers nobody calls directly is wasted build time.

The two-step pipeline: structure cache, then output

The README describes phpDocumentor as a two-step process. First it parses your application and produces a cache containing the application structure. Then it renders that structure into the output format you asked for. The README explicitly frames the intermediate structure as reusable: you can use it to power your own tools or formatters.

That split explains the incremental parsing option. If you keep the Structure file from a previous run, the README states you get an additional performance boost of up to 80% on top of the processing speed increase it already claims. The numbers in the README are the project's own: peak memory usage is stated as under 20MB for small projects, 40MB for medium ones, and 100MB for large frameworks. Treat those as documentation claims rather than measurements you can rely on without checking your own tree.

The parsing layer is where the interesting engineering sits. The README lists support for namespaces, closures, generics, and DocBlock types that native PHP cannot express. Generics matter here because PHP's own type syntax has no way to write them, so a tool that renders them as first-class types is doing work the language does not. The repository layout reflects this: there is a src/ tree, a separate tests/ tree, and a config/ directory, plus a phpstan.neon and a rector.php at the top level, which is what you would expect from a codebase that parses other people's code and has to defend its own type handling.

Installing phpDocumentor and running a first build

phpDocumentor requires PHP 8.1 or higher to run, though the README notes that code from earlier PHP versions can still be analyzed. There are four install routes. The README recommends phive, the phar.io package manager, and gives this command, which installs the tool and trusts a specific GPG key:

bash
phive install phpDocumentor --trust-gpg-keys 6DA3ACC4991FFAE5

After that, the README shows the binary being executed as php tools/phpDocumentor. The PHAR route is manual: download the phar file from the GitHub releases page and run it with php phpDocumentor.phar. The Docker route pulls the published image and mounts the current directory into /data, which is the volume the image declares:

bash
docker pull phpdoc/phpdoc
docker run --rm -v $(pwd):/data phpdoc/phpdoc

The repository's own Dockerfile sets the entrypoint to /opt/phpdoc/bin/phpdoc and sets PHPDOC_ENV=prod, so the image behaves like the command-line tool with your working directory as the input.

The first real run is short. The README gives the canonical invocation, where -d is the source directory to parse and -t is the folder to write into:

bash
phpdoc run -d <SOURCE_DIRECTORY> -t <TARGET_DIRECTORY>

Run phpdoc run -h for the full option list. For anything beyond a one-off, phpDocumentor reads a configuration file named phpdoc.xml or phpdoc.dist.xml by default; the README points at the online documentation for the format rather than describing it, and the repository ships a phpdoc.dist.xml at the top level that you can read as a worked example of the keys it expects.

Class diagrams need PlantUML, and the failure is quiet

Every template shipped with phpDocumentor supports class diagrams derived from the code it read. Rendering those diagrams requires PlantUML to be installed on the machine running phpDocumentor. The README is candid about what happens without it: warnings about the missing PlantUML can be ignored, but your documentation will contain dead links. The diagrams are also off by default; you turn them on with --setting=graphs.enabled=true.

That combination is the sharpest limitation in the project. A build can succeed, exit cleanly, and still ship a site with broken diagram links, because the missing dependency is reported as a warning rather than a hard failure. If you run phpDocumentor in CI and nobody reads the log, you find out from a user. The Dockerfile in the repository installs openjdk-21-jre-headless, which is the Java runtime PlantUML needs, so the published image is set up for this; a phive or PHAR install on a bare runner is not.

The second limitation is the Composer install. There is a phpdocumentor package on Packagist, and the README devotes a section to explaining why you should not use it. The argument is dependency conflict: phpDocumentor's libraries are used by many other packages, and the README states that two of its libraries have more than 150 million downloads each, which makes a clash between its dependencies and yours likely. The README says the project does not endorse or actively support installing via Composer. If your build process only permits Composer, phpDocumentor is the wrong tool for that environment, not because it will not work but because you are outside the supported path.

phpDocumentor versus Doxygen and static analysers

The obvious comparison is Doxygen. Doxygen is a general-purpose documentation generator that handles many languages from one configuration file, and it has its own comment syntax that resembles JavaDoc. phpDocumentor is PHP-only and reads the PHPDoc conventions that PHP IDEs and static analysers already understand. The practical difference is that phpDocumentor's parser knows PHP-specific constructs: the README calls out namespaces, closures and generics, and generics support is the one that matters most, because a multi-language tool has no reason to model PHP's generic type syntax. If your repository is polyglot, Doxygen covers more ground with one tool. If it is PHP and you want the docblocks your editor already highlights to be the source of truth, phpDocumentor is the closer fit.

The second comparison is with static analysers such as PHPStan, which the repository itself uses. Those tools read the same docblocks but for a different purpose: they check whether the declared types hold. phpDocumentor renders them for humans. They are complementary, not alternatives, and the repository's own phpstan.neon is evidence that the maintainers run both. A team that has already invested in docblock types for analysis gets more out of phpDocumentor than a team that has not, because the same annotations feed both tools.

Maintenance, licensing and what an upgrade costs

The project is MIT licensed, which is permissive: you can use, modify and redistribute it, including in commercial products, provided the copyright notice and licence text are preserved. That is a summary of the licence identifier in the repository, not legal advice; read the LICENSE file at the top level before you depend on it.

The repository is not archived, and the last push was on 2026-09-21. The most recent tagged release in the list is v3.10.0 from 2026-05-13, preceded by v3.9.1 on 2025-11-25 and v3.9.0 on 2025-11-21. So the cadence is roughly a stable release every few months, with commits landing between them. The README states that v3 is the latest stable line. There are no nightly releases; the README explains that a phar artifact is built during each pipeline and can be downloaded from the Artifacts section of a successful QA workflow if you want to test unreleased code. That is a deliberate choice, and it means the bleeding edge is available but unsupported.

Upgrade cost is dominated by two things. First, the runtime floor: PHP 8.1 or higher, which is a constraint on your build runner rather than on the code you analyze. Second, template compatibility. The README advertises easy template building, describing it as calling one task and editing three files, but a custom template is still code you own and it is the part most likely to break across a minor version. If you use the bundled templates, an upgrade is mostly a version bump. If you maintain your own, budget time to re-check it against each release.

Editorial conclusion

Adopt phpDocumentor if you maintain a PHP library or framework whose public API needs a browsable reference and you already write DocBlocks. Skip it if your code is undocumented and you expect the generator to fill the gap, if you need class diagrams but cannot install PlantUML, or if Composer is your only allowed install channel. Before committing, verify three things on your own tree: that PHP 8.1 or higher is available to the runner, that phpdoc run -d src -t build/api produces the expected output, and that the phpdoc.xml you write is picked up rather than the defaults.

Frequently asked questions

How do I use phpDocumentor on a PHP project?

Install it with phive, the PHAR, or Docker, then run phpdoc run -d <SOURCE_DIRECTORY> -t <TARGET_DIRECTORY>. The -d argument is the code to parse and -t is the folder the generated documentation is written to.

Is phpDocumentor a good alternative to Doxygen for PHP?

phpDocumentor is PHP-only and understands PHP-specific constructs such as namespaces, closures and generics, which the README highlights. Doxygen covers multiple languages from one configuration, so it is the better fit for a polyglot repository and phpDocumentor is the closer fit for a PHP-only one.

What is the difference between phpDocumentor and Doxygen?

phpDocumentor parses PHP source and DocBlock comments and is built around PHP's type system, including generics that native PHP cannot express. Doxygen is a general-purpose generator that handles many languages, so it does not model PHP-specific type syntax the same way.

Official sources

  1. License: MIT
  2. phpDocumentor/phpDocumentor on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/phpdocumentor-phpdocumentor.svg)](https://hysenlabs.com/projects/phpdocumentor-phpdocumentor)