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 {
}

Это работает достаточно хорошо, основная проблема заключается в том, что код становится заваленным конкретными классами. Они могут быть вложенными, поэтому части конфигурации могут быть повторно использованы.