2011-01-15 11 views
24

sto utilizzando l'API Reflection in PHP per tirare un (PHPDoc) stringa DocComment da un metodoparsing PHP Doc Commenti in una struttura dati

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

Ciò restituirà una stringa che sembra qualcosa di simile (a seconda sul modo in cui il metodo è stato documentato)

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

ci sono metodi o funzioni built-in che può analizzare un commento di stringa PHP Doc in una struttura di dati?

$object = some_magic_function_or_method($comment_string); 

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

In mancanza di questo, quale parte del PHPDoc source code dovrei esaminare al fare da solo.

Mancanza e/o in aggiunta a ciò, c'è codice di terze parti che è considerato "migliore" a questo che il codice PHPDoc?

Mi rendo conto che l'analisi di queste stringhe non è scienza missilistica, o addirittura informatica, ma preferirei una libreria/routine/metodo ben collaudata che è stata costruita per gestire un sacco di janky, semi-non corretto Codice PHP che potrebbe esistere in natura.

risposta

20

Sono sorpreso che questo non è stato ancora menzionato: per quanto riguarda l'utilizzo di Zend_Reflection di Zend Framework? Questo può tornare utile specialmente se si lavora con un software basato su Zend Framework come Magento.

Vedere lo Zend Framework Manual per alcuni esempi di codice e lo API Documentation per i metodi disponibili.

Ci sono diversi modi per farlo:

  • passare un nome di file per Zend_Reflection_File.
  • Passa un oggetto a Zend_Reflection_Class.
  • Passa un oggetto e un nome di metodo a Zend_Reflection_Method.
  • Se si dispone solo della stringa di commenti, è anche possibile riunire il codice per una piccola classe dummy, salvarlo in un file temporaneo e passare tale file in Zend_Reflection_File.

Andiamo per il caso semplice e assumiamo che tu abbia una classe esistente che vuoi ispezionare.

Il codice dovrebbe essere simile a questo (non testato, ti prego perdonami):

$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(); 
} 
+0

Bello, grazie per averlo condiviso. –

+0

Prego. –

+0

Funziona con i tratti? Come se una classe utilizzasse i tratti, raccoglierà il docblock corretto? – srcspider

3

Dalla tua descrizione Posso solo sospettare ciò che stai cercando di fare (documentazione del codice PHP). Dato che non dichiari perché stai cercando di farlo, posso solo speculare.

Forse dovresti provare un altro approccio. Per documentare il codice PHP (se è quello che stai provando) userei Doxygen e dall'aspetto del tuo commento sul codice, è già formattato per doxygen.

Con Graphviz, Doxygen esegue anche rendering di diagrammi di classe e alberi di chiamata.

+2

che sto facendo quello che ho detto che sto facendo, cercando di analizzare una serie di commenti PHP Documenter in un data struttura. Spero che qualcuno qui possa fornire il codice esatto che posso usare per fare questo per salvarmi attraverso un albero dei sorgenti sconosciuto. –

4

È sempre possibile visualizzare la sorgente da phpDoc. Il codice è sotto LGPL, quindi se decidi di copiarlo dovrai concedere in licenza il tuo software con la stessa licenza E aggiungere correttamente le notifiche corrette.

MODIFICA: a meno che, come @ Samuel Herzog, abbia notato che lo si utilizza come libreria.

Grazie a @ Samuel Herzog per il chiarimento.

+0

fino a quando si utilizza la parte phpDoc solo come libreria è perfettamente adatto per utilizzare il proprio modello di licenza. le informazioni sulla licenza non erano né richieste né corrette. –

+0

Mi scuso se non è stato chiaro dalla mia domanda, ma so che posso usare il codice sorgente PHPDoc. Spero che qualcuno qui possa fornire il codice esatto che posso usare per fare questo per salvarmi attraverso un albero dei sorgenti sconosciuto. –

6

È possibile utilizzare DocBlox (http://github.com/mvriel/docblox) per generare una struttura di dati XML per l'utente; è possibile installare DocBlox utilizzando PEAR e quindi eseguire il comando:

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

Questo genererà un file chiamato structure.xml che contiene tutti i meta-dati circa il vostro codice sorgente, tra cui docblocks analizzati.

O

Offriamo le DocBlox_Reflection_DocBlock* classi per analizzare direttamente un pezzo di testo DocBlock.

Questo si può fare per fare in modo che avete caricamento automatico abilitato (o includere tutti DocBlox_Reflection_DocBlock * file) ed eseguire il seguente:

$parsed = new DocBlox_Reflection_DocBlock($docblock); 

In seguito è possibile utilizzare la getters per estrarre le informazioni che si desidera.

Nota: non è necessario rimuovere gli asterischi; la classe Reflection si prende cura di questo.

+0

DocBlox è morto. Sembra essere stato fuso in questo https://github.com/phpDocumentor/phpDocumentor2 – mpen

+0

Infatti phpDocumentor e DocBlox si sono fusi insieme per formare phpDocumentor2 – mvriel

+1

Appena notato che sei l'autore. Ragazzo subdolo. – mpen

2

Se stai cercando di leggere i tag @ e i loro valori, usare preg_match sarebbe la soluzione migliore.

16

È possibile utilizzare il "DocBlockParser" classe dalla Fabien PotencierSami ("Yet Another PHP API Generatore di documentazione") progetto open-source.
Prima di tutto, prendi Sami dal GitHub.
Questo è un esempio di come usarlo:

<?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); 
} 

?> 

Ed ecco l'output della pagina di prova:

** 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 
+2

Questo approccio non funziona più. Sembra che nel 2014 abbiano deciso di nixare il proprio parser in favore dell'utilizzo del parser DocBlox/phpDocumentor. –

+0

Funziona con la vecchia versione di Sami: https://github.com/FriendsOfPHP/Sami/tree/v1.2 –