Подтвердить что ты не робот

Анализ комментариев PHP Doc в структуру данных

Я использую Reflection API в PHP, чтобы вытащить строку DocComment (PHPDoc) из метода

$r = new ReflectionMethod($object);
$comment = $r->getDocComment();

Это вернет строку, которая выглядит примерно так (в зависимости от того, насколько хорошо документирован метод)

/**
* Does this great things
*
* @param string $thing
* @return Some_Great_Thing
*/

Есть ли встроенные методы или функции, которые могут анализировать строку комментариев PHP Doc Comment в структуру данных?

$object = some_magic_function_or_method($comment_string);

echo 'Returns a: ', $object->return;

Если этого не делать, то какую часть исходного кода PHPDoc я должен смотреть на это самостоятельно.

Отсутствие и/или дополнение к этому, есть ли сторонний код, который считается "лучше" при этом, что код PHPDoc?

Я понимаю, что синтаксический анализ этих строк - это не наука о ракетах или даже компьютерная наука, но я бы предпочел хорошо протестированную библиотеку/рутину/метод, который был построен для обработки большого количества janky, полунеправильного PHP Doc-код, который может существовать в дикой природе.

4b9b3361

Ответ 1

Я удивлен, что это еще не упоминалось: как насчет использования Zend_Reflection Zend Framework? Это может пригодиться, особенно если вы работаете с программным обеспечением, основанным на Zend Framework, например Magento.

См. Руководство по Zend Framework для некоторых примеров кода и Документация API для доступных методов.

Существуют разные способы сделать это:

  • Передайте имя файла Zend_Reflection_File.
  • Передайте объект Zend_Reflection_Class.
  • Передайте объект и имя метода в Zend_Reflection_Method.
  • Если у вас действительно есть только строка комментариев, вы даже можете скомпоновать код для небольшого класса фиктивного типа, сохраните его во временном файле и передайте этот файл Zend_Reflection_File.

Отпустим простой случай и предположим, что у вас есть существующий класс, который вы хотите проверить.

Код будет таким (непроверенный, пожалуйста, простите меня):

$method = new Zend_Reflection_Method($class, 'yourMethod');
$docblock = $method->getDocBlock();

if ($docBlock->hasTag('return')) {
    $tagReturn = $docBlock->getTag('return'); // $tagReturn is an instance of Zend_Reflection_Docblock_Tag_Return
    echo "Returns a: " . $tagReturn->getType() . "<br>";
    echo "Comment for return type: " . $tagReturn->getDescription();
}

Ответ 2

Вы можете использовать класс DocBlockParser из Fabien Potencier Сами ( "Еще один генератор документации API PHP" ) с открытым исходным кодом.
Прежде всего, получите саами от GitHub.
Это пример того, как его использовать:

<?php

require_once 'Sami/Parser/DocBlockParser.php';
require_once 'Sami/Parser/Node/DocBlockNode.php';

class TestClass {
    /**
     * This is the short description.
     *  
     * This is the 1st line of the long description 
     * This is the 2nd line of the long description 
     * This is the 3rd line of the long description   
     *  
     * @param bool|string $foo sometimes a boolean, sometimes a string (or, could have just used "mixed")
     * @param bool|int $bar sometimes a boolean, sometimes an int (again, could have just used "mixed") 
     * @return string de-html_entitied string (no entities at all)
     */
    public function another_test($foo, $bar) {
        return strtr($foo,array_flip(get_html_translation_table(HTML_ENTITIES)));
    }
}

use Sami\Parser\DocBlockParser;
use Sami\Parser\Node\DocBlockNode;

try {
    $method = new ReflectionMethod('TestClass', 'another_test');
    $comment = $method->getDocComment();
    if ($comment !== FALSE) {
        $dbp = new DocBlockParser();
        $doc = $dbp->parse($comment);
        echo "\n** getDesc:\n";
        print_r($doc->getDesc());
        echo "\n** getTags:\n";
        print_r($doc->getTags());
        echo "\n** getTag('param'):\n";
        print_r($doc->getTag('param'));
        echo "\n** getErrors:\n";
        print_r($doc->getErrors());
        echo "\n** getOtherTags:\n";
        print_r($doc->getOtherTags());
        echo "\n** getShortDesc:\n";
        print_r($doc->getShortDesc());
        echo "\n** getLongDesc:\n";
        print_r($doc->getLongDesc());
    }
} catch (Exception $e) {
    print_r($e);
}

?>

И вот результат тестовой страницы:

** getDesc:
This is the short description.

This is the 1st line of the long description 
This is the 2nd line of the long description 
This is the 3rd line of the long description
** getTags:
Array
(
    [param] => Array
        (
            [0] => Array
                (
                    [0] => Array
                        (
                            [0] => Array
                                (
                                    [0] => bool
                                    [1] => 
                                )

                            [1] => Array
                                (
                                    [0] => string
                                    [1] => 
                                )

                        )

                    [1] => foo
                    [2] => sometimes a boolean, sometimes a string (or, could have just used "mixed")
                )

            [1] => Array
                (
                    [0] => Array
                        (
                            [0] => Array
                                (
                                    [0] => bool
                                    [1] => 
                                )

                            [1] => Array
                                (
                                    [0] => int
                                    [1] => 
                                )

                        )

                    [1] => bar
                    [2] => sometimes a boolean, sometimes an int (again, could have just used "mixed")
                )

        )

    [return] => Array
        (
            [0] => Array
                (
                    [0] => Array
                        (
                            [0] => Array
                                (
                                    [0] => string
                                    [1] => 
                                )

                        )

                    [1] => de-html_entitied string (no entities at all)
                )

        )

)

** getTag('param'):
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => Array
                        (
                            [0] => bool
                            [1] => 
                        )

                    [1] => Array
                        (
                            [0] => string
                            [1] => 
                        )

                )

            [1] => foo
            [2] => sometimes a boolean, sometimes a string (or, could have just used "mixed")
        )

    [1] => Array
        (
            [0] => Array
                (
                    [0] => Array
                        (
                            [0] => bool
                            [1] => 
                        )

                    [1] => Array
                        (
                            [0] => int
                            [1] => 
                        )

                )

            [1] => bar
            [2] => sometimes a boolean, sometimes an int (again, could have just used "mixed")
        )

)

** getErrors:
Array
(
)

** getOtherTags:
Array
(
)

** getShortDesc:
This is the short description.
** getLongDesc:
This is the 1st line of the long description 
This is the 2nd line of the long description 
This is the 3rd line of the long description

Ответ 3

Вы можете использовать DocBlox (http://github.com/mvriel/docblox) для создания структуры данных XML для вас; вы можете установить DocBlox, используя PEAR, а затем запустите команду:

docblox parse -d [FOLDER] -t [TARGET_LOCATION]

Это создаст файл с именем structure.xml, который содержит все метаданные о вашем исходном коде, включая проанализированные docблоки.

ИЛИ

Вы можете использовать классы DocBlox_Reflection_DocBlock * для прямого анализа фрагмента текста DocBlock.

Это можно сделать, если вы включили автозагрузку (или включили все файлы DocBlox_Reflection_DocBlock *) и выполните следующие действия:

$parsed = new DocBlox_Reflection_DocBlock($docblock);

Затем вы можете использовать getters для извлечения необходимой информации.

Примечание: вам не нужно удалять звездочки; класс Reflection позаботится об этом.

Ответ 6

Вы всегда можете просмотреть источник из phpDoc. Код находится под LGPL, поэтому, если вы решите его скопировать, вам нужно будет лицензировать свое программное обеспечение под одной лицензией и правильно добавить правильную уведомления.

EDIT: Если, как @Samuel Herzog, если вы используете его как библиотеку.

Спасибо @Samuel Herzog за разъяснения.

Ответ 7

Из вашего описания я могу только подозревать, что вы пытаетесь сделать (документация на PHP-код). Поскольку вы не указываете, почему вы пытаетесь это сделать, я могу только предполагать.

Возможно, вам стоит попробовать другой подход. Чтобы документировать PHP-код (если это то, что вы пытаетесь), я бы использовал Doxygen и из внешнего вида вашего комментария кода, он уже отформатирован для doxygen.

С Graphviz, Doxygen также визуализирует диаграммы классов и деревья вызовов.

Ответ 8

Если вы пытаетесь прочитать в тегах @и их значениях, то наилучшим решением будет использование preg_match.

Ответ 9

Я предлагаю вам взглянуть на http://code.google.com/p/php-annotations/

Код достаточно прост для изменения/понимания при необходимости.

Ответ 10

Как указано в одном из приведенных выше ответов, вы можете использовать phpDocumentor. Если вы используете композитор, просто добавьте "phpdocumentor/reflection-docblock": "~ 2.0" на ваш блок "требовать".

Посмотрите это на примере: https://github.com/abdulla16/decoupled-app/blob/master/composer.json

Примеры использования см. в: https://github.com/abdulla16/decoupled-app/blob/master/Container/Container.php