I have a proposal where I wanted to check the mood first before I write an RFC.
Background:
While looking into better documenting our Web APIs we figured our preferred solution is parameter typing plus DocComments and do both basic checks on input values (e.g. string vs. int vs. array) and automatically generate OpenAPI docs.
So we ended up with something like
/**
- Search for entries matching query
- @param $query Terms to search for in database
- @param $num Maximum number of entries returned, default is 10
*/
function api_search(string $query, ?int $num = 10) { ... }
The downside of this is that the parameters have to be mentioned twice (DocComment and parameter list) and the documentation can diverge from the implementation.
So we looked into using parameters DocComments like
/**
- Search for entries matching query
/
function api_search(
string $query /* Terms to search for in database /,
?int $num = 10 /* Maximum number of entries returned */,
) { ... }
and realized that this is currently not supported.
Part 1:
When I looked at the parser I realized that PHP already had the syntax in place for this and it was only missing
a) storing the DocComments with the parameters (zend_arg_info)
b) providing a method getDocComment() in ReflectionParameter
c) allowing DocComments behind the parameter instead of before them.
While part a) and b) are pretty straightforward I also slightly changed the syntax to allow the DocComments after the parameter definition but before the comma starting the next parameter. This keeps the implementation very simple with the limitation of having to move the comma behind the DocComment.
Rationale for c) We strongly favored the comment to be behind instead of before the parameter name + default value and found the trailing comma a valid compromise.
Part 2:
I realized that PHP already had (almost) everything in place to also have DocComments for the internal functions.
So I extended zend_internal_arg_info and zend_internal_function_info to allow this.
Part 3:
Then I went down the rabbit hole and wrote a script to extract the information from the doc-en DocBook source and add them to the stub files.
To do this I added a script build/add_doccomments.php and changed gen_stub.php to use the new macros when applicable.
Implementation:
You can find the code at
https://github.com/php/php-src/compare/master...chschneider:php-src:param-doccomment-all
with the 3 first commits representing the 3 parts above and the 4th commit containing the files automatically generated by the add_doccomments.php and gen_stub.php build scripts so you don't need to run them.
Missing part:
- Add tests for ReflectionParameter::getDocComment()
- Include add_doccomments.php in the build process, currently is has to be called manually.
Backwards compatibility:
As I added a field to the Zend arg_info structure it is an ABI change which needs external modules to be recompiled to match it.
I assume this is acceptable for PHP 8.6, correct?
Otherwise the only change is the additional method getDocComment() for ReflectionParameter, everything else is backwards compatible.
Is there interest in the community to add this to the next PHP version?
Should I rewrite this into an RFC or are the other comments/recommendations before I do that?
Regards,
- Chris