例2:リフレクションによるPHPドキュメントの生成
次は、リフレクションを使用してPHPクラスのドキュメントを生成する例です。この処理には、クラス内部を掘り下げて解析する必要があり、したがってリフレクションAPIのメソッドを多用します。
まずは、HTMLベースの簡単なコンソールを用意します。ドキュメントの対象となるクラスの名前をクライアントから指定するためのコンソールです。次のような簡単なコードのコンソールで問題ありません。
<html> <head> <b>Provide the class name to be documentated: <br /><br /></b> </head> <body> <form method="get" action="generatingDocumentation.php"> <input type="text" name="class"> <input type="submit" value="Generate documentation"> <input type="reset" value="Reset"> </form> </body> </html>
ドキュメント生成アプリケーションの中核となるのは、「generatingDocumentation.php」のコードです。長いコードなので、以降では重要な部分だけを抜粋して示します。コード全体については、本稿のダウンロードサンプルに収録されている「generatingDocumentation.php」ファイルを参照してください。まず、ユーザーからコンソールを通じて送信されたクラス名を取得し、ファイルの拡張子を付加して、目的のクラスをインクルードします。その後で、出力ドキュメントの書き込み先となるファイルを開きます。
//get the class name to be documentated $className=$_GET['class']; //paste the name class with the extension .inc $classNameExtension=$_GET['class'].".inc"; $b=$_GET['class']; //include the $classNameExtension class include($classNameExtension); //get a ReflectionClass for the $className class $reflection=new ReflectionClass($className); //prepare the output $hf=fopen("PTD.html","w");
次に、クラスの各部分に対して反復処理を行い、必要な情報(クラスがサポートするインターフェイス、親クラス名(ある場合)、定数、プロパティ、メソッドとその全パラメータなど)を取得します。そして、これらの情報すべてを、説明のコメントと共に、ドキュメントファイルに書き込みます。以下、クラスのメソッドとパラメータを取得してドキュメント化する部分のコードの抜粋を示します。
//get information about methods $methods=$reflection->getMethods(); if($methods != null) { fwrite($hf,"\t<tr><td align=\"center\"". " colspan=\"0\"><font face=\"arial\"". " size=\"2\" color=\"purple\">Methods:". "</td><td align=\"center\" colspan=\"0\">". "<font face=\"arial\" size=\"2\"". " color=\"black\"><b>Name</b></td>". "<td align=\"center\" colspan=\"0\">". "<font face=\"arial\" size=\"2\"". " color=\"black\"><b>Modifiers</b>". "</td><td align=\"center\" colspan=\"0\">". "<font face=\"arial\" size=\"2\"". " color=\"black\"><b>Parameters</b>". "</td><td align=\"center\" colspan=\"0\">". "<font face=\"arial\" size=\"2\"". " color=\"black\"><b>Description</b>". "</td></tr>\n"); foreach($methods as $in) { fwrite($hf,"\t<tr><td></td><td>"); fwrite($hf,$in->getName()); if($in->isConstructor()) { fwrite($hf," [c]"); } fwrite($hf,"</td><td>"); if ($in->isPublic()) { fwrite($hf,"[public]"); } if ($in->isPrivate()) { fwrite($hf,"[private]"); } if ($in->isProtected()) { fwrite($hf,"[protected]"); } if ($in->isAbstract()) { fwrite($hf,"[abstract]"); } if ($in->isFinal()) { fwrite($hf,"[final]"); } if ($in->isStatic()) { fwrite($hf,"[static]"); } fwrite($hf,"</td>"); $parameters=$in->getParameters(); if($parameters != null) { fwrite($hf,"<td align=\"center\">"); $nr_parameters=count($parameters); foreach($parameters as $out) { fwrite($hf,"$"); fwrite($hf,$out->getName()); if($out->isPassedByReference()) { fwrite($hf," [&] "); } if($out->allowsNull()) { fwrite($hf," [+] "); } } fwrite($hf,"</td>"); }else { fwrite($hf,"<td></td>"); } fwrite($hf,"<td align=\"center\"><i>"); fwrite($hf,$in->getDocComment()); fwrite($hf,"</i>\n\t</td></tr>\n"); } }
たとえば、このPHPドキュメントツールでリスト1のテストクラスを指定すると、図3のような情報が出力されます。
このように、新しいリフレクションAPIはリフレクション機能の便利な実装であり、本稿のPHPドキュメントツールのような比較的複雑なアプリケーションの開発に利用できます。実行すべきクラスやメソッドをデザイン時に判断できない場合には、リフレクションは特に便利です。

