PHPDoc для массивов аргументов переменной длины
Есть ли синтаксис для документирования функций, которые принимают один конфигурационный массив, а не отдельные параметры?
Я имею в виду библиотеки CodeIgniter, которые используют механизм, подобный этому:
<?php
//
// Library definition
//
class MyLibrary {
var $foo;
var $bar;
var $baz;
// ... and many more vars...
/* Following is how CodeIgniter documents their built-in libraries,
* which is mostly useless. AFAIK they should be specifying a name
* and description for their @param (which they don't) and omitting
* @return for constructors
*/
/**
* @access public
* @param array
* @return void
*/
function MyLibrary($config = array()) {
foreach ($config as $key => $value) {
$this->$key = $value;
}
}
}
//
// Library usage:
//
// Iniitialize our configuration parameters
$config['foo'] = 'test';
$config['bar'] = 4;
$config['baz'] = array('x', 'y', 'z');
$x = new MyLibrary($config);
?>
Итак, мой вопрос заключается в том, есть ли какой-то завершенный способ документирования массива конфигурации за пределами чисто текстового описания? Собственно, указав правильный @param [type] [name] [desc]
, который позволяет PHPDoc анализировать полезные значения?
В противоположность этому, CodeIgniter действительно просто перезаписывает свои собственные значения с помощью тех, которые передаются через массив $config, как указано выше, что позволяет вам закрывать частные члены. Я не поклонник, но я застрял с ним.
Ответы
Ответ 1
Я никогда не видел "хорошего" способа документирования этого - и я никогда не видел ничего, что могло бы использоваться IDE (например, Eclipse PDT) для параметров, намекающих либо: - (
Я бы сказал, "делай, как твоя инфраструктура", но, как ты сказал, что это делает, здесь не совсем хорошо...
Возможно, быстрый или сортированный список возможных ключей может быть лучше, чем ничего; примерно так:
@param array $config [key1=>int, otherKey=>string]
Не уверен, как это интерпретируется phpDocumentor или IDE... Но может быть стоит попробовать?
Это, кстати, одна из причин, почему я склонен избегать такого способа передачи параметров - по крайней мере, когда не слишком много (необязательных) параметров для метода.
Ответ 2
Правильная запись массива @param для массивов такова, как указано в PHPlint
Вы можете использовать его для документирования массива config полезным образом:
Пример:
/**
* Does stuff
*
* @param array[int|string]array[string]Object $config
*
* @return array[int]string
*/
public function foo(array $config)
{
// do stuff here
return array('foo', 'bar', 'baz');
}
Ответ 3
Вы можете сделать это:
/**
* @param array $param1
* @param string $param1['hello']
*/
function hey($param1)
{
}
и netbeans подберут его, но phpdoc испортит документацию
Ответ 4
Я всегда использую теги <pre>
в таких ситуациях. Пример:.
/**
* @param array $ops An array of options with the following keys:<pre>
* foo: (string) Some description...
* bar: (array) An array of bar data, with the following keys:
* boo: (string) ...
* far: (int) ...
* baz: (bool) ...
* </pre>
*/
Большинство IDE и генераторов документации, которые я использовал, как представляется, делают это разумным образом, хотя, конечно, они не предоставляют проверки типа или проверки параметров массива.
Ответ 5
В настоящее время нет "официального" (как в "поддерживаемом несколькими инструментами" ) способа сделать это.
PHP FIG обсуждает его в данный момент на https://groups.google.com/d/topic/php-fig/o4ko1XsGtAw/discussion
Ответ 6
Текстовое описание, независимо от степени полноты, которую вы хотите, действительно является вашим единственным вариантом. Вы можете сделать это как можно более разборчивым, но инструменты анализа кода (phpDocumentor, IDE-поддержка) не имеют способа узнать, как ваш $array
на самом деле структурирован во время выполнения.
Я согласен со многими комментаторами в том, что написание кода таким образом меняет удобство кодирования для четкости кода.
Ответ 7
Я использовал классы.
<?php
class MyLibrary {
var $foo;
var $bar;
var $baz;
/**
* @param MyLibraryConfig|null $config
*/
function MyLibrary( $config = null ) {
if ( isset( $config->foo ) ) {
$this->foo = $config->foo;
}
if ( isset( $config->baz ) ) {
$this->baz = $config->baz;
}
if ( isset( $config->bar ) ) {
$this->bar = $config->bar;
}
}
}
/**
* @property string $foo
* @property int $bar
* @property array $baz
*/
class MyLibraryConfig {
}
Это работает достаточно хорошо, основная проблема заключается в том, что код становится заваленным конкретными классами. Они могут быть вложенными, поэтому части конфигурации могут быть повторно использованы.