前書き
PHPにはクラス情報を取得するReflectionClassという関数があります。
この関数を使うとメソッドなどの行番も取得できるため、この行番情報とfile関数を併用することでコード内のメソッド一覧を取得できるのではと考えてみました。
サンプルコード
use Composer\Autoload\ClassMapGenerator;
use LogicException;
use ReflectionClass;
/**
* Class ReflectionClassCode
*/
class ReflectionClassCode
{
/**
* クラス内のメソッドのコードを取得する
*
* @param array $class_paths
* @param int|null $filter
* @return array
*/
public function getMethodCode(array $class_paths, int $filter = null)
{
$classes = [];
foreach ($class_paths as $class_path) {
foreach (ClassMapGenerator::createMap($class_path) as $model => $class_file_path) {
$code_texts = file($class_file_path);
$code_texts = collect($code_texts)->prepend('')->all();
$method_codes = [];
$reflection = new ReflectionClass($model);
// 継承クラスのメソッドは除外したものを取得する
$methods = collect($reflection->getMethods($filter))->where('class', $model)->all();
foreach ($methods as $method) {
if ($method->getName() === '__construct') {
continue;
}
if (empty($method->getDocComment())) {
throw new LogicException('メソッドのPhoDocが未定義です。必ず入力して下さい');
}
$code_length = $method->getEndLine() - $method->getStartLine() + 1;
$method_code_doc_comments = $method->getDocComment() . PHP_EOL;
$method_code = array_slice($code_texts, $method->getStartLine(), $code_length);
$method_codes[$method->getName()] = ' ' . $method_code_doc_comments . collect($method_code)->join('');
}
$classes[$class_file_path] = $method_codes;
}
}
return $classes;
}
/**
* クラス内のメソッドのコードを取得する
*
* @param string $class_path
* @param int|null $filter
* @return array
*/
public function findMethodCode(string $class_path, int $filter = null)
{
return collect($this->getMethodCode([$class_path], $filter))->first();
}
}