Encontrar el archivo PHP (en tiempo de ejecución) donde se definió una clase

111

¿Hay alguna reflexión / introspección / magia en PHP que le permita encontrar el archivo PHP donde se definió una clase (o función) en particular?

En otras palabras, tengo el nombre de una clase PHP o un objeto instanciado. Quiero pasar esto a algo (función, clase de reflexión, etc.) que devolvería la ruta del sistema de archivos donde se definió la clase.

/path/to/class/definition.php

Me doy cuenta de que podría usar ( get_included_files())para obtener una lista de todos los archivos que se han incluido hasta ahora y luego analizarlos todos manualmente, pero eso es mucho acceso al sistema de archivos para un solo intento.

También me doy cuenta de que podría escribir código adicional en nuestro mecanismo de carga automática que almacena esta información en algún lugar. Sin embargo, modificar la __autoload existente está fuera de los límites en la situación que tengo en mente.

Sería interesante escuchar sobre extensiones que pueden hacer esto, pero en última instancia, me gustaría algo que se pueda ejecutar en una instalación "estándar".

Alan Storm
fuente
2
Magento me trajo aquí: -]
Alan
@alan es bueno ver algunos nombres de propiedad allí.
Alan Storm

Respuestas:

225

Tratar ReflectionClass

Ejemplo:

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

Esto volverá falsecuando no se pueda encontrar el nombre del archivo, por ejemplo, en clases nativas.

Gordon
fuente
10

Para ReflectionClass en un archivo con espacio de nombres , agregue un prefijo "\" para hacerlo global de la siguiente manera:

$ reflector = nuevo \ ReflectionClass ('FOO');

De lo contrario, generará un error dicho ReflectionClass en un espacio de nombres no definido. No tenía derecho a hacer comentarios sobre la respuesta anterior, así que escribo esto como una respuesta complementaria.

Jevin
fuente
0

si tuviera una carpeta de inclusión, podría ejecutar un comando de script de shell para "grep" para "class $ className" haciendo: $filename = ``grep -r "class $className" $includesFolder/*\y devolvería en qué archivo estaba. Aparte de eso, no creo que haya ninguna magia función para que PHP lo haga por ti.

Seaux
fuente
3
Curiosidad honesta y no idiota aquí. ¿Qué te hizo pensar que esta respuesta era mejor que la idea que ya había considerado y rechazado? "Me doy cuenta de que podría usar (get_included_files ()) para obtener una lista de todos los archivos que se han incluido hasta ahora y luego analizarlos todos manualmente, pero eso es mucho acceso al sistema de archivos para un solo intento".
Alan Storm
porque es una línea a diferencia de la cantidad de líneas que se necesitarían para escribir un analizador en PHP y la función grep está compilada en C, creo, y probablemente mucho más rápido de lo que se hubiera escrito.
Seaux
Ah, lo tengo. Mi preocupación real era el acceso repetido al disco a cada uno de los archivos una y otra vez para hacer esto (es algo que sucederá mucho en la herramienta que estoy construyendo) y no la cantidad de código que intentaré aclarar a continuación. hora. (FYI: Deberías mirar ack. ¡Es mucho mejor que grep!)
Alan Storm
ack o awk? Me encanta awk, en realidad es mi lenguaje de programación favorito, pero más gente usa grep con regularidad ... es "más limpio" para cosas así de simples
Seaux
No awk, ack: betterthangrep.com Es un reemplazo de perl back grep que está optimizado para proyectos basados ​​en códigos de búsqueda. Es genial.
Alan Storm