Вывести имена классов php

PHP — получить все имена классов в определенном пространстве имен

Я пробовал get_declared_classes() внутри getAllClasses() , но MyClass1 и MyClass2 не были в списке. Как я могу это сделать?

12 ответов

Общий подход заключается в том, чтобы получить все полностью определенные имена классов (класс с полным пространством имен) в вашем проекте, а затем выполнить фильтрацию по требуемому пространству имен.

PHP предлагает некоторые встроенные функции для получения этих классов (get_declared_classes и т.д.), Но они не смогут найти классы, которые не были загружены (include/require), поэтому он не будет работать, как ожидается, с автозагрузчиками (например, Composer для пример). Это серьезная проблема, поскольку использование автозагрузчиков очень распространено.

Таким образом, ваше последнее средство — найти все файлы PHP самостоятельно и проанализировать их, чтобы извлечь их пространство имен и класс:

$path = __DIR__; $fqcns = array(); $allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); $phpFiles = new RegexIterator($allFiles, '/\.php$/'); foreach ($phpFiles as $phpFile) < $content = file_get_contents($phpFile->getRealPath()); $tokens = token_get_all($content); $namespace = ''; for ($index = 0; isset($tokens[$index]); $index++) < if (!isset($tokens[$index][0])) < continue; >if (T_NAMESPACE === $tokens[$index][0]) < $index += 2; // Skip namespace keyword and whitespace while (isset($tokens[$index]) && is_array($tokens[$index])) < $namespace .= $tokens[$index++][1]; >> if (T_CLASS === $tokens[$index][0] && T_WHITESPACE === $tokens[$index + 1][0] && T_STRING === $tokens[$index + 2][0]) < $index += 2; // Skip class keyword and whitespace $fqcns[] = $namespace.'\\'.$tokens[$index][1]; # break if you have one class per file (psr-4 compliant) # otherwise you'll need to handle class constants (Foo::class) break; >> > 

Если вы следуете стандартам PSR 0 или PSR 4 (ваше дерево каталогов отражает ваше пространство имен), вам не нужно ничего фильтровать: просто укажите путь, который соответствует требуемому пространству имен.

Читайте также:  Язык php логические операторы

Если вы не любите копировать/вставлять приведенные выше фрагменты кода, вы можете просто установить эту библиотеку: https://github.com/gnugat/nomo-spaco. Если вы используете PHP> = 5.5, вы также можете использовать следующую библиотеку: https://github.com/hanneskod/classtools.

Обновление: так как этот ответ стал несколько популярным, я создал упаковочный пакет, чтобы упростить вещи. Он содержит в основном то, что я описал здесь, без необходимости добавлять класс самостоятельно или настраивать $appRoot вручную. Это может в конечном итоге поддерживать больше, чем просто PSR-4.

$ composer require haydenpierce/class-finder 

Смотрите больше информации в файле README.

Я не был доволен ни одним из решений здесь, поэтому я решил построить свой класс, чтобы справиться с этим. Это решение требует, чтобы вы были:

Короче говоря, этот класс пытается выяснить, где классы фактически живут в вашей файловой системе, на основе пространств имен, которые вы определили в composer.json . Например, классы, определенные в пространстве имен Backup\Test находятся в /home/hpierce/BackupApplicationRoot/src/Test . Этому можно доверять, потому что сопоставление структуры каталога с пространством имен требуется PSR-4:

Смежные имена подпространств имен после «префикса пространства имен» соответствуют подкаталогу в «базовом каталоге», в котором разделители пространства имен представляют разделители каталога. Имя подкаталога ДОЛЖНО совпадать с регистром имен под-пространства имен.

Возможно, вам придется настроить appRoot чтобы он указывал на каталог, содержащий composer.json .

, $files); return array_filter($classes, function($possibleClass)< return class_exists($possibleClass); >); > private static function getDefinedNamespaces() < $composerJsonPath = self::appRoot . 'composer.json'; $composerConfig = json_decode(file_get_contents($composerJsonPath)); //Apparently PHP doesn't like hyphens, so we use variable variables instead. $psr4 = "psr-4"; return (array) $composerConfig->autoload->$psr4; > private static function getNamespaceDirectory($namespace) < $composerNamespaces = self::getDefinedNamespaces(); $namespaceFragments = explode('\\', $namespace); $undefinedNamespaceFragments = []; while($namespaceFragments) < $possibleNamespace = implode('\\', $namespaceFragments) . '\\'; if(array_key_exists($possibleNamespace, $composerNamespaces))< return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments)); >array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments)); > return false; > > 

Источник

get_declared_classes

Возвращает массив имён объявленных классов в текущем скрипте.

Замечание:

Учтите также, что в зависимости от модулей, собранных или загруженных в PHP, может варьироваться число дополнительных классов. Это означает, что вы не сможете использовать собственные классы с данными именами. Список предопределённых классов находится в разделе дополнения «Предопределённые классы».

Список изменений

Версия Описание
7.4.0 Ранее get_declared_classes() всегда возвращала родительские классы перед дочерними классами. Это больше не так. Для возвращаемого значения get_declared_classes() конкретный порядок не гарантируется.

Примеры

Пример #1 Пример использования get_declared_classes()

Результатом выполнения данного примера будет что-то подобное:

Array ( [0] => stdClass [1] => __PHP_Incomplete_Class [2] => Directory )

Смотрите также

  • class_exists() — Проверяет, был ли объявлен класс
  • get_declared_interfaces() — Возвращает массив всех объявленных интерфейсов
  • get_defined_functions() — Возвращает массив всех определённых функций

User Contributed Notes 9 notes

$class = ‘myclass’ ;
$instance = new $class ();

?>

This function could also be used to determine the names of classes defined in a particular file by calling it before and after include. It’s hardly a pointless function.

The array returned by this function will be in the order the classes were defined / included / required and this order does not appear to change.

//define classone
class classone

//define classtwo
class classtwo

//This will show X classes (built-ins, extensions etc) with
//classone and classtwo as the last two elements

//define classthree
class classthree

//Shows the same result as before with class three and four appended
print_r ( get_declared_classes ());

Array
(
[0] => stdClass
[1] . other defined classes.
[10] => classone
[11] => classtwo
)

Array
(
[0] => stdClass
[1] . other defined classes.
[10] => classone
[11] => classtwo
[12] => classthree
[13] => classfour
)

get-declared-classes makes no sense at all, if u maybe, later for production, merge class files in one package file.

lets say: package.php
print_r(get_declared_classes());
class declaredHere < >
print_r(get_declared_classes());

so in this case, the declaredHerr class is defined at the first call of print_r();
because PHP-complier runs a hole file and declare Stuff before running the code.

But (Lovely PHP):
print_r(get_declared_classes());
if(true)class declaredHere < >
>
print_r(get_declared_classes());
Will print the declaredHere class only in the second print_r.

Summary:
* in PHP 5.1 class names have case preserved
* contrary, in PHP 4.4 class names are downcased, withe exception of a few build-in ones

The get_declared_classes() funcition returns the list of names with case preserved, as of PHP 5.1 series (prolly 5.0 too, but i have no way to test it right now). Since PHP generally is caseless in regard to names of classes, this may come at a surprise. Also, this could potentially break older code asssuming downcased list.

Take extra care when checking for existence of a class. Following example is, potentially, error prone:

A sure-fire (while slower) way would be to iterate over the array and normalize case to, say, lower:

$exists = FALSE ;
$className = strtolower ( $className );
foreach ( get_declared_classes () as $c ) if ( $className === strtolower ( $c ) ) $exists = TRUE ;
break;
>
> ?>

Optimization of the above snippet is left as a simple excercise to the reader 😉
— dexen deVries

classes can’t be unloaded. probably not very practical to implement that in a future version. I wouldn’t go out of my way to do it if I were zend. you’re better off finding a workaround. it’s better programming technique to find a way around having to do that anyway.

you cannot remove them. they are «defined», which happens when the class is being loaded from the parser. you just deleted an instance of a class.

This function considers only classes and subclasses. Not subsubclasses.

In fact I have code that provides an abstract class and then classes using this abstract class. Further I have subclasses to my concrete classes — which is why my subclasses are not listed within the returned array.

In PHP5, you don’t get declared interfaces by calling this function.
To get interfaces you should use get_declared_interfaces(). However, to check if an interface is already defined, you should use class_exists()! This is strange, but PHP team does not think so.

those above comments are too old.
now, whatever the order is, the output will be the same:

?>

will output the same result.

  • Функции работы с классами и объектами
    • class_​alias
    • class_​exists
    • enum_​exists
    • get_​called_​class
    • get_​class_​methods
    • get_​class_​vars
    • get_​class
    • get_​declared_​classes
    • get_​declared_​interfaces
    • get_​declared_​traits
    • get_​mangled_​object_​vars
    • get_​object_​vars
    • get_​parent_​class
    • interface_​exists
    • is_​a
    • is_​subclass_​of
    • method_​exists
    • property_​exists
    • trait_​exists
    • _​_​autoload

    Источник

    get_class

    Возвращает имя класса, экземпляром которого является объект object .

    Список параметров

    Тестируемый объект. Внутри класса этот параметр может быть опущен.

    Возвращаемые значения

    Возвращает имя класса, к которому принадлежит экземпляр object . Возвращает FALSE , если object не является объектом.

    Если параметр object опущен внутри класса, будет возвращено имя этого класса.

    Ошибки

    Если get_class() будет вызвана с чем-то другим, не являющимся объектом, будет вызвана ошибка уровня E_WARNING .

    Список изменений

    Версия Описание
    5.3.0 NULL стал значением по умолчанию для параметра object , поэтому передача NULL в object теперь имеет тот же самый эффект, как и отсутствие какой-либо передачи вообще.

    Примеры

    Пример #1 Использование get_class()

    class foo function name ()
    echo «My name is » , get_class ( $this ) , «\n» ;
    >
    >

    // создание объекта
    $bar = new foo ();

    // внешний вызов
    echo «Its name is » , get_class ( $bar ) , «\n» ;

    // внутренний вызов
    $bar -> name ();

    Результат выполнения данного примера:

    Its name is foo My name is foo

    Пример #2 Использование get_class() в родительском классе

    abstract class bar public function __construct ()
    var_dump ( get_class ( $this ));
    var_dump ( get_class ());
    >
    >

    Результат выполнения данного примера:

    Смотрите также

    • get_called_class() — Имя класса, полученное с помощью позднего статического связывания
    • get_parent_class() — Возвращает имя родительского класса для объекта или класса
    • gettype() — Возвращает тип переменной
    • is_subclass_of() — Проверяет, содержит ли объект в своем дереве предков указанный класс

    Источник

Оцените статью