What's the best way to document the elements of an array when it is a parameter to a method? For example, using the PHPDoc headers, I might have something like:
@param array $data
What this doesn't tell me is what elements are mandatory in the array, and what are optional elements. I imagine this should go in the explanation of the method. Something like:
array: $data
============
int $id Required
name $string Required
town $string Optional
/**
* @param array $data
*
* @var $data[id] int, required
* @var $data[name] string, required
* @var $data[town] string, required
*/
This example of using doctrine and zf2 example:
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
* @Form\Attributes({"type":"hidden"})
*/
protected $id;
/**
* @ORM\Column(type="string")
* @Form\Type("Zend\Form\Element\Text")
* @Form\Required({"required":"true"})
* @Form\Filter({"name":"StripTags"})
* @Form\Filter({"name":"StringTrim"})
* @Form\Validator({"name":"StringLength", "options":{"min":"5"}})
* @Form\Options({"label":"First name"})
*/
protected $firstName;
If you have such a complex array with constraints for every single member, I wouldn't use an anonymous array but rather a well defined object. With an array, you can never be sure what it holds, that's somewhat like passing "Object" in e.g. Java, which you rarely would consider a good choice.
However, there is the possibility of a little hinting, when you array contains objects of a certain type as explained here, but that's not a really good answer to your question.
If you really need the parameter as an array, you might document it the way you proposed in the method's description; however, if you use an object as parameter, you'd have additional support in modern IDEs (IntelliSense and so on).
EDIT: I mean, for me the question would be "why would I want to use an anonymous array instead of a self defined type" - and besides simplicity (which will backfire as technical debt later if you maintain and extend your code), I cannot think of a reason, especially compared to what you gain in using a user defined type (self documented code, constraints visible and made explicit by standard methods and so on).
If you just need a dump of data, you might want to go with a simple array, but since you're already thinking about optional and required keys, that screams for a user defined type.
EDIT2: Regarding your comment about if your already have an array as source: I'm not sure whether you need to pass it on as an array or do "mapping" operations as soon as you receive the array (e.g. as $_POST or as return value from some third party library or PHP internal functions or such).
I suppose one could argue that it's not the model's business to interpret data generated by views (e.g. HTML forms which POST data), but rather the controller's resonsibility to react accordingly to the input and transfer the model in the appropriate state. What I mean by this is that you could do something like this if you receive e.g. an array as $_POST:
$customer = new Customer();
$customer->setId($_POST['id']);
$customer->setName($_POST['name']);
$customer->setTown($_POST['town']);
And handle errors as soon as you access the $customer, e.g. throwing exceptions if the name is not set (i.e. $_POST['name']
was empty or such). This way, you use the source array to call setters on the object instead of e.g. passing the array to a factory like Customer::buildByHttpPostData(array $data)
and thereby delegating the knowledge of the view's details (names of HTML input tags and such).
Bottom line is, there's no "standard" way to declare required or optional array keys, and of course you can describe those constraints in the method description, but perhaps you can circumvent this by keeping with supported ways like PHPDoc comments on setters or getters.
Of course, there may be better ways to approach the problem, and perhaps somebody comes up with a better answer how to handle it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With