Skip to content

Instantly share code, notes, and snippets.

@mvriel
Created October 2, 2012 19:49
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save mvriel/3822861 to your computer and use it in GitHub Desktop.
Save mvriel/3822861 to your computer and use it in GitHub Desktop.
Option arrays in PHPDoc
<?php
/*
This code sample demonstrates several style for representing an option array with
the following fields: name, label, type_id, visible, default.
When designing this we should keep in mind that the option key may be represented
by either a literal or a (class)constant. As such we mix and match those for
illustrative purposes.
*/
const NAME = "name";
/**
* ...
*
* @param array $options [description]
* @option string NAME [description]
* @option string "label" [description]
* @option integer "type_id" [description]
* @option boolean "visible" [description]
* @option string "default" [description]
*
* @return void
*/
function ryan_parman($options = array())
{
}
/**
* ...
*
* @param mixed[] $options [description] {
* @type string NAME [description]
* @type string "label" [description]
* @type integer "type_id" [description]
* @type boolean "visible" [description]
* @type string "default" [description]
* }
*
* @return void
*/
function mike_van_riel($options = array())
{
}
/**
* ...
*
* @param `Options` $options [description]
*
* @struct Options {
* @type string NAME [description]
* @type string "label" [description]
* @type integer "type_id" [description]
* @type boolean "visible" [description]
* @type string "default" [description]
* }
*
* @return void
*/
function mike_van_riel2($options = array())
{
}
@moufmouf
Copy link

moufmouf commented Oct 8, 2012

Hi Mike,

I like pretty much what you are proposing here.
Now, this is slightly off-topic, but I have a remark to do about the way arrays are commented.

So far, we had this annotation:
@type MyObject[]

This documentation is ok for documenting arrays.
Now, in this Gist, we have a new proposal for documenting option arrays.

Yet, we are still lacking a way to make the difference between indexed arrays and associative arrays (which are the same "array" object in PHP but have a completely different meaning)
My thought is that by reading documentation, we should know whether the developer expects us to provide a plain array, or a hashtable.

Could we try to find a way to make sure the docblock captures the difference between an indexed array and a hashtable?

On the PSR mailing list, I proposed this notation:
@type MyObject[int]
vs
@type MyObject[string]

Any thought about that? Any better notation idea?

Also, on a completely different topic, in an option array, in your current proposal, there is no way to tell the difference between a parameter that is required and one that is optional. Maybe we could add a third keyword, this way:

 *     @param array $options {
 *         [description]
 * 
 *         @option string  NAME      required [description]
 *         @option string  "label"   required [description]
 *         @option integer "type_id" required[description]
 *         @option boolean "visible" optional [description]
 *         @option string  "default" [description]
 *     }

What to you think?

@mvriel
Copy link
Author

mvriel commented Oct 8, 2012

Hi @moufmouf,

For a discussion about array types; please see this gist: https://gist.github.com/3823010

Regarding your suggestion with regards to mentioning whether an option is required or not; I am in doubt whether and if so, how, that should be captured.
Perhaps other people have ideas on this as well?

@skyzyx
Copy link

skyzyx commented Oct 14, 2012

So, one more thing to think about: Nested hashes.

Some of us need to support nested hashes of options for one reason or another. How well would this scale for that case? Would the "inner" sections be able to recurse (potentially) infinitely?

@totten
Copy link

totten commented Oct 18, 2012

The "@param { ... }" notation looks pleasant (like in "mike_van_riel()" and "ryan_parman2()"), but it's a special case. The @struct approach deals better with the general case -- and the general case is "developers using PHP arrays to define non-OOP data structures". While I'm a fan of OOP, it's a simple fact that there's a tremendous amount of non-OOP PHP code, and it's useful to provide documentation and tooling for it. I posted a more detailed discussion here:

https://groups.google.com/forum/?hl=en&fromgroups=#!searchin/php-fig/non-PHP$20typing/php-fig/o4ko1XsGtAw/-UcmR-ghhqYJ

Regarding nested hashes: if one is nesting hashes, I think the @struct approach provides greater expressiveness and maintainability than the "@param {...}" approach. For example, there's no equivalent of this in the @param notation:

/**
 * @param Widget widget_options
 * @struct Widget {
 *   @option int length
 *   @option int width
 *   @option Gizmo[string] gizmos
 * }
 * @struct Gizmo {
 *   @option int foo;
 *   @option string bar;
 *  }
 */
function create_widget($widget_options)

Of course, the "create_widget" function seems badly designed and needs refactoring. As one goes through the process of refactoring it, one will likely pull out code involving that nested structure (Gizmo) and create new functions or classes that work directly with Gizmo. The refactoring will be made simpler by having a clear, named type for "Gizmo".

@skyzyx
Copy link

skyzyx commented Nov 1, 2012

Is anybody working on a way to parse the contents of braces (e.g., {...}) yet?

Whether or not we use param, option, struct, or anything else, they all seem to depend on the ability to parse the contents of braces as sub-blocks.

I just wanted to know before I start this work myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment