ethnaAdminにphpdocの解析を追加
結局コメントも取れないと意味ないねってことで、コメントの解析。PEARを見たところすぐに使えそうなツールはないんですよね(涙目)
PHP_Parser_DocblockParserってのがあるんですが、docblockってPECL使っているし。。。
今回は正規表現でがしがし持ってきています。token_get_all()でトークンに分割して、T_DOC_COMMENTだった場合には正規表現で抜き出し。次に続くトークンがclassとかfunctionの場合には解析したDOCをくっつけています。
action-form: name: /Contact/Initialize realname: www/app/action/Contact/Initialize.php extends: Neko_Form_ContactInput form: type: type: VAR_TYPE_STRING form_type: FORM_TYPE_HIDDEN name: お問い合わせ種別 contact_info: type: VAR_TYPE_STRING form_type: FORM_TYPE_TEXT required: true mbmax: 50 name: お名前(漢字) contact_info_kana: type: VAR_TYPE_STRING form_type: FORM_TYPE_TEXT required: true custom: checkHiragana mbmax: 50 name: お名前(ふりがな) phpdoc: file: items: - name: author body: {$author} - name: package body: Neko - name: version body: | $Id: skel.action.php,v 1.10 2006/11/06 14:31:24 cocoitiban Exp $ body: Contact/Initialize.php class: - name: Neko_Form_ContactInitialize extends: Neko_Form_ContactInput doc: items: - name: author body: {$author} - name: access body: public - name: package body: Neko body: contact_initializeフォームの実装 - name: Neko_Action_ContactInitialize extends: Neko_ActionClass doc: items: - name: author body: {$author} - name: access body: public - name: package body: Neko body: > contact_initializeアクションの実装 function: - name: prepare doc: items: - name: access body: public - name: return body: > string 遷移名(正常終了ならnull, 処理終了ならfalse) body: > contact_initializeアクションの前処理 - name: perform doc: items: - name: access body: public - name: return body: string 遷移名 body: > contact_initializeアクションの実装 return: - name: contact_input function: perform doc:
こんな感じで取得してきています。
<?php //----------------------------------------------------------------------------- // アクション検索 //----------------------------------------------------------------------------- function find_comments($str){ $tokens = token_get_all($str); $doc = null; $system = false; $data = array(); $mode = ''; foreach ($tokens as $token){ if (is_array($token)){ switch ($token[0]){ case T_COMMENT: break; case T_DOC_COMMENT: $doc = doc_block($token[1]); if( $system == false ){ // 一番最初はファイルの説明 $data['file'] = $doc; $system = true; $doc = null; } break; default: switch( $token[1] ){ case 'class': $mode = 'class'; break; case 'extends': if( $mode == 'class' ){ $mode = 'extends'; } break; case 'function': $mode = 'function'; break; case 'return': $mode = 'return'; break; default: if( trim( $token[1] ) ){ if( $mode == 'class' ){ $class_name = $token[1]; } elseif( $mode == 'extends' ){ $data['class'][] = array( 'name' => $class_name, 'extends' => $token[1], 'doc' => $doc ); $doc = null; $mode = ''; $class_name = ''; } elseif( $mode == 'function' ){ $data['function'][] = array( 'name' => $token[1], 'doc' => $doc ); $doc = null; $mode = ''; $function = $token[1]; } elseif( $mode == 'return' ){ if( strtolower( $token[1] ) != 'null' ){ $token[1] = str_replace( "'", '', $token[1] ); $token[1] = str_replace( '"', '', $token[1] ); $data['return'][] = array( 'name' => $token[1], 'function' => $function, 'doc' => $doc ); } $doc = null; $mode = ''; } else { $doc = null; $mode = ''; } } } break; } } else { } } return $data; } //----------------------------------------------------------------------------- // phpdoc解説 //----------------------------------------------------------------------------- function doc_block($str){ $doc = array(); // コメントの閉じを削除 $str = preg_replace('/\*\//', '', $str ); // パラメータ $doc['items'] = array(); preg_match_all('/\*[ ]+@(.*)/', $str, $match); foreach($match[1] as $item){ preg_match('/(.*?)[ ]+(.*)/', $item, $match2); $item = array(); $item['name'] = $match2[1]; $item['body'] = $match2[2]; $doc['items'][] = $item; } // ボディ取得 $str = preg_replace('/\*[ ]+@(.*)/', '', $str ); preg_match_all('/\*[ ]+(.*)/', $str, $match); $body = array(); foreach($match[1] as $item){ if( trim( $item ) ){ $body[] = trim( $item ); } } if( $body ){ $doc['body'] = implode( "\n", $body ); } return $doc; }
抜き出し部分です。THE力技〜!
てかphpdoc書いてないじゃん(笑)