Finding the PHP File (at run time) where a Class was Defined

62,157

Solution 1

Try ReflectionClass

Example:

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

This will return false when the filename cannot be found, e.g. on native classes.

Solution 2

For ReflectionClass in a namespaced file, add a prefix "\" to make it global as following:

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

Or else, it will generate an error said ReflectionClass in a namespace not defined. I didn't have rights to make comment for above answer, so I write this as a supplement answer.

Solution 3

Using a reflector you can build a function like this:

function file_by_function( $function_name ){
    if( function_exists( $function_name ) ){
        $reflector = new \ReflectionFunction( $function_name );
    }
    elseif( class_exists( $function_name ) ){
        $reflector = new \ReflectionClass( $function_name );
    }
    else{
        return false;
    }
    return $reflector->getFileName();
}

file_by_function( 'Foo' ) will return the file path where Foo is defined, both if Foo is a function or a class and false if it's not possible to find the file

Share:
62,157
Alan Storm
Author by

Alan Storm

Portland based Web Developer/Programmer/Engineer. Projects include No Frills Magento Layout, the only Magento layout book you'll ever need and Commerce Bug, the debugging extension for the Magento Ecommerce system. If you're interested in low cost, in-depth mentoring/tutoring, checkout my Patreon campaign.

Updated on March 27, 2021

Comments

  • Alan Storm
    Alan Storm about 3 years

    Is there any reflection/introspection/magic in PHP that will let you find the PHP file where a particular class (or function) was defined?

    In other words, I have the name of a PHP class, or an instantiated object. I want to pass this to something (function, Reflection class, etc.) that would return the file system path where the class was defined.

    /path/to/class/definition.php
    

    I realize I could use (get_included_files()) to get a list of all the files that have been included so far and then parse them all manually, but that's a lot of file system access for a single attempt.

    I also realize I could write some additional code in our __autoload mechanism that caches this information somewhere. However, modifying the existing __autoload is off limits in the situation I have in mind.

    Hearing about extensions that can do this would be interesting, but I'd ultimately like something that can run on a "stock" install.

  • Alan Storm
    Alan Storm about 14 years
    Honest, non-asshole curiosity here. What made you think this answer was any better than the idea I'd already considered and rejected? " I realize I could use (get_included_files()) to get a list of all the files that have been included so far and then parse them all manually, but that's a lot of file system access for a single attempt."
  • Seaux
    Seaux about 14 years
    because its one line as opposed to however many lines it'd take to write a parser in PHP and the grep function is compiled C, i think, and likely much faster than whatever would have been written.
  • Alan Storm
    Alan Storm about 14 years
    Ah, got it. My actual concern was repeated disk access to each of the files over and over again to do this (it's something that will happen a lot in the tool I'm building) and not the amount of code I'll try to make that clearer next time. (FYI: You should look into ack. It's way better than grep!)
  • Seaux
    Seaux about 14 years
    ack or awk? I love awk, its actually my fav programming language, but more people use grep regularly...its "cleaner" for stuff this simple
  • Alan Storm
    Alan Storm about 14 years
    Not awk, ack: betterthangrep.com It's perl back grep replacement that's optimized for search code based projects. It's great.