2010-05-01 63 views
4

請考慮下面的代碼與我試圖解析只有第一個PHPDoc的風格註釋在一個文件中(不使用任何其他庫)(放在$數據變量用於測試文件的內容):如何使用PHP解析phpDoc樣式註釋塊?

$data = " 
/** 
* @file A lot of info about this file 
*   Could even continue on the next line 
* @author [email protected] 
* @version 2010-05-01 
* @todo do stuff... 
*/ 

/** 
* Comment bij functie bar() 
* @param Array met dingen 
*/ 
function bar($baz) { 
    echo $baz; 
} 
"; 

$data = trim(preg_replace('/\r?\n *\* */', ' ', $data)); 
preg_match_all('/@([a-z]+)\s+(.*?)\s*(?=$|@[a-z]+\s)/s', $data, $matches); 
$info = array_combine($matches[1], $matches[2]); 
print_r($info) 

這幾乎工程,除了一個事實,即一切 @todo後(包括bar()註釋塊和代碼)被認爲是@todo值:

Array (
    [file] => A lot of info about this file Could even continue on the next line 
    [author] => [email protected] 
    [version] => 2010-05-01 
    [todo] => do stuff.../

    /** Comment bij functie bar() 
    [param] => Array met dingen/
    function bar() { 
     echo ; 
    } 
) 

如何確實需要我的代碼被改變,使得只有Ť他正在解析第一個註釋塊(換句話說:在遇到第一個「* /」之後解析應該停止?

+1

考慮一下s字符串像'$ s ='/ **不是phpDoc @file ... * /';'放在第一個phpDoc之前的情況。換句話說:使用正則表達式,您將獲得100%可靠的解決方案。 – 2010-05-01 09:01:23

回答

6

使用PCRE編寫解析器會導致麻煩。我建議先依靠tokenizerreflection。然後,爲doc區塊實際實施一個解析器更爲安全,該解析器可以處理phpdoc格式所支持的所有情況(所有庫都以此結束)。

+0

感謝您的快速回復。實際上,我必須遍歷許多文件,收集每個文件的第一個註釋塊(只有描述文件的註釋塊;我不需要收集描述函數,方法等的其他註釋塊)。使用標記器的缺點是我不能告訴token_get_all()在找到第一個註釋塊後停止查找註釋塊,這導致一個**巨大的數組需要大約20-30秒的編譯時間,這太長了,因爲我必須重新編譯對每一個頁面請求(不要問...) – Pr0no 2010-05-01 09:39:50

+0

正則表達式的好處是,可以指示它停止查找文件的第一個註釋塊後,導致更好的性能或者是有解決方法(看到我的代碼下面使用tokenizer)? foreach($ files as $ file){ $ data = file(「$ file.inc.php」)); $ tokens = token_get_all($ data); foreach($ tokens as $ token){ list($ id,$ text)= $ token; switch($ id){ case T_DOC_COMMENT: $ return [] = $ token; 休息; 默認值: break; } } print_r($ return); – Pr0no 2010-05-01 09:40:31