Поиск файла PHP (во время выполнения), в котором был определен класс

111

Есть ли в PHP какое-либо отражение / самоанализ / магия, которая позволит вам найти файл PHP, в котором был определен конкретный класс (или функция)?

Другими словами, у меня есть имя класса PHP или созданного объекта. Я хочу передать это чему-то (функции, классу Reflection и т. Д.), Который вернет путь к файловой системе, в которой был определен класс.

/path/to/class/definition.php

Я понимаю, что могу использовать ( get_included_files())чтобы получить список всех файлов, которые были включены до сих пор, а затем проанализировать их все вручную, но это большой объем доступа к файловой системе для одной попытки.

Я также понимаю, что могу написать дополнительный код в нашем механизме __autoload, который где-то кэширует эту информацию. Однако изменение существующего __autoload запрещено в ситуации, которую я имею в виду.

Было бы интересно услышать о расширениях, которые могут это сделать, но в конечном итоге я бы хотел что-то, что могло бы работать на "стандартной" установке.

Алан Сторм
источник
2
Magento привел меня сюда: -]
Алан
@alan приятно видеть там написание названия собственности.
Алан Сторм

Ответы:

225

Пытаться ReflectionClass

Пример:

class Foo {}
$reflector = new \ReflectionClass('Foo');
echo $reflector->getFileName();

Это вернется, falseесли имя файла не может быть найдено, например, в собственных классах.

Гордон
источник
10

Для ReflectionClass в файле с пространством имен добавьте префикс «\», чтобы сделать его глобальным, как показано ниже:

$ отражатель = новый \ ReflectionClass ('FOO');

В противном случае он сгенерирует ошибку ReflectionClass в не определенном пространстве имен. У меня не было прав комментировать приведенный выше ответ, поэтому я пишу это как дополнительный ответ.

Джевин
источник
0

если у вас была папка include, вы могли бы запустить команду сценария оболочки для «grep» для «class $ className», выполнив: $filename = ``grep -r "class $className" $includesFolder/*\и она вернет, в каком файле он был. Кроме этого, я не думаю, что есть какая-то магия функция для PHP, чтобы сделать это за вас.

Seaux
источник
3
Честное, не засранное любопытство. Что заставило вас думать, что этот ответ был лучше, чем идея, которую я уже рассмотрел и отверг? «Я понимаю, что могу использовать (get_included_files ()), чтобы получить список всех файлов, которые были включены до сих пор, а затем проанализировать их все вручную, но это требует большого доступа к файловой системе для одной попытки».
Алан Сторм,
потому что это одна строка, а не столько строк, сколько потребуется для написания синтаксического анализатора на PHP, а функция grep скомпилирована на C, я думаю, и, вероятно, намного быстрее, чем все, что было бы написано.
Seaux,
Ах, понял. На самом деле меня беспокоил повторный доступ к диску для каждого файла снова и снова, чтобы сделать это (это то, что часто будет происходить в инструменте, который я создаю), а не объем кода, который я постараюсь сделать более понятным в следующий раз. время. (К вашему сведению: вам следует изучить ack. Это намного лучше, чем grep!)
Алан Сторм,
акк или awk? Я люблю awk, на самом деле это мой любимый язык программирования, но все больше людей используют grep регулярно ... его «чище» для таких простых вещей
Seaux
Не awk, ack: betterthangrep.com Это замена grep на perl back, оптимизированная для проектов на основе кода поиска. Здорово.
Алан Сторм,