phpDocumentor, patched to read and print the types the DiscordPHP family documents its API surface with. It is the toolchain the class references are built from; it is not a library and nothing ships it as a dependency.
DiscordPHP writes a leading ? on a class-level @property to mark a field
Discord treats as optional, and spells nullability out separately:
/**
* @property ?int|null $handler Whether the interaction is handled by the app.
*/Stock phpDocumentor turns every tag written that way into an error and drops it, so the property never reaches the published reference. On DiscordPHP alone that was 339 failing tags and 420 missing members.
The cause is upstream of phpDocumentor: phpstan/phpdoc-parser reads a leading
? as ending the type and leaves the |null unread, so the tag fails to parse.
That is deliberate — ?int|null is a parse error in PHP, and the union types
RFC disallowed ?Foo|Bar on readability grounds
(phpstan/phpdoc-parser#321
was closed for exactly that reason). Rather than rewrite several hundred
docblocks across the family, the toolchain is taught to read them.
Two patches, applied by cweagans/composer-patches:
| Package | Change |
|---|---|
phpstan/phpdoc-parser |
A ? carries over the ` |
phpdocumentor/phpdocumentor |
NullableAdapter prints a nullable type as ?T instead of expanding it to T|null, so a type is documented the way it was written. |
Note that the second patch changes nullable rendering everywhere, not only for
?T|null tags: an ordinary @var ?Guild now renders as ?Guild rather than
Guild|null.
Install it as its own project next to the library being documented, and run it
from the library's root so phpdoc.dist.xml is picked up:
- name: Install phpDocumentor
run: composer create-project discord-php/phpdoc-tool phpdoc-tool --no-interaction
- name: Build class reference
run: php phpdoc-tool/vendor/bin/phpdocIt is installed as a project rather than required as a dependency on purpose.
composer-patches v1 resolves relative patch paths against the root package
and applies patches as each package is installed, so patches carried by a
dependency would be looked for in the wrong place and would not exist on disk
yet when the packages they patch are installed. As the root, its own patches
apply normally.
Add /phpdoc-tool to the consuming repository's .gitignore.
league/uri is held at ~7.5.0. phpDocumentor 3.10 declares ^7.5, but
7.8 tightened base-URI validation and phpDocumentor then fails to resolve a
relative dsn in phpdoc.dist.xml with:
The base URI must be an absolute URI or null
7.5.1 is what the official PHAR ships, so that is what is pinned here. Drop the pin once phpDocumentor supports 7.8.
phpdocumentor/phpdocumentor is an ordinary ^3.10 constraint — run
composer update here and commit the lock. composer-exit-on-patch-failure is
on, so a release that a patch no longer applies to fails the build loudly
instead of quietly publishing an incomplete reference.
MIT, matching both patched upstreams. The files under patches/ are diffs
against MIT-licensed code from
phpDocumentor and
phpstan/phpdoc-parser.