Skip to content

Instantly share code, notes, and snippets.

@perrelet
Last active January 24, 2025 16:46
Show Gist options
  • Save perrelet/9d8ce7f1c5e3f9191c0ba992a22a272a to your computer and use it in GitHub Desktop.
Save perrelet/9d8ce7f1c5e3f9191c0ba992a22a272a to your computer and use it in GitHub Desktop.
PHP - Extract Class Name from File
<?php
function extract_class_name ($file) {
// https://stackoverflow.com/questions/7153000/get-class-name-from-file
// fix: $class = $tokens[$i+2][1]; ---> if (is_array($tokens[$i+2])) $class = $tokens[$i+2][1]; Avoids 'Uninitialized string offset 1' when using 'static::class'
// fix: if ($tokens[$j][0] === T_STRING) { ---> if ($tokens[$j][0] === T_STRING || $tokens[$j][0] === T_NAME_QUALIFIED) { Handle files with sub-namespaces (T_NAME_QUALIFIED PHP 8.0.0+)
// fix: add: if ($tokens[$j] === ';') break; Class declarations can't contain a semi-colon. Bailing early speeds things up and prevents confusing lines containing '::class' with the class declaration.
$fp = fopen($file, 'r');
$class = $namespace = $buffer = '';
$i = 0;
while (!$class) {
if (feof($fp)) break;
$buffer .= fread($fp, 512);
$tokens = token_get_all($buffer);
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 || $tokens[$j][0] === T_NAME_QUALIFIED) {
$namespace .= '\\'.$tokens[$j][1];
} else if ($tokens[$j] === '{' || $tokens[$j] === ';') {
break;
}
}
}
if ($tokens[$i][0] === T_CLASS) {
for ($j=$i+1;$j<count($tokens);$j++) {
if ($tokens[$j] === ';') break;
if ($tokens[$j] === '{') {
if (is_array($tokens[$i+2])) $class = $tokens[$i+2][1];
}
}
}
}
}
return $namespace ? $namespace . "\\" . $class : $class;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment