ClassGetter.php
<?php
namespace Tlf\Stuff;
/**
* Utility class for PHP-specific stuff
*/
class Php {
/**
* Get all classes in a directory
* @param $classDir A directory to search
* @return array `['class'=>$class, 'interfaces'=>['interface1','interface2']]`
*/
static public function classesFromDir($classDir){
$classes = [];
if (is_dir($classDir)){
$files = scandir($classDir);
foreach ($files as $file){
if ($file=='.'||$file=='..'){
continue;
}
$path = $classDir.'/'.$file;
$ext = pathinfo($path,PATHINFO_EXTENSION);
if ($ext!='php')continue;
include_once($path);
$class = self::getClassFromFile($path);
$classes[] = ['class'=>$class, 'interfaces'=>self::getInterfacesFromClass($class)];
}
}
return $classes;
}
/**
* Get a fully qualified class name from a file
* @param $file a file path
* @return a class name
*/
static public function getClassFromFile($file){
$fp = fopen($file, 'r');
$class = $namespace = $buffer = '';
$i = 0;
while (!$class) {
if (feof($fp)) break;
$buffer .= fread($fp, 512);
ob_start();
$tokens = @token_get_all($buffer);
$err = ob_get_clean();
// if (true&&strlen($err)>0){
// echo $buffer;
// echo $err."\n";
// echo $class."\n";
// echo "\n".$file;
// print_r($tokens);
// }
if (strpos($buffer, '{') === false) continue;
for (;$i<count($tokens);$i++) {
if ($tokens[$i][0] === T_NAMESPACE
) {
for ($j=$i+1;$j<count($tokens); $j++) {
if ($tokens[$j][0] === T_STRING) {
$namespace .= '\\'.$tokens[$j][1];
} else if ($tokens[$j] === '{' || $tokens[$j] === ';') {
break;
}
}
}
if ($tokens[$i][0] === T_CLASS
||$tokens[$i][0]=== T_INTERFACE
||$tokens[$i][0]=== T_TRAIT
) {
for ($j=$i+1;$j<count($tokens);$j++) {
if ($tokens[$j] === '{') {
$class = $tokens[$i+2][1];
}
}
}
}
}
if ($class=='')return '';
return $namespace.'\\'.$class;
}
static public function getInterfacesFromClass($class){
if ($class=='')return [];
$ref = new \ReflectionClass($class);
return $ref->getInterfaceNames();
}
}