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

Reply via email to