Viewed   70 times

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.

 Answers

1

Try ReflectionClass

  • ReflectionClass::getFileName — Gets a filename

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.

Friday, September 23, 2022
5

Chances are you are importing the file that declares the class more than once. This can be symptomatic of includes/requires getting out of control so you may need to simply your structure.

One alternative approach is to use autoload to load classes to avoid this kind of problem. Another is to only use include_once or require_once. I generally prefer to use require with a simple structure.

Tuesday, December 13, 2022
 
saifur
 
5

I would get it like this:

$class = new ReflectionClass('Some_class_name');
$properties = array_filter($class->getProperties(), function($prop) use($class){ 
    return $prop->getDeclaringClass()->getName() == $class->getName();
});

So basically get all properties and iterate through them checking if they were declared in class we reflected.

Tuesday, November 8, 2022
1

How about

  • ReflectionProperty::getValue - Gets the properties value.

In your case:

foreach ($api->getProperties() as $propertie)
{
    print $propertie->getName() . "n";
    print $propertie->getValue($t);
}

On a sidenote, since your object has only public members, you could just as well iterate it directly

foreach ($t as $propertie => $value)
{
    print $propertie . "n";
    print $value;
}

or fetch them with get_object_vars into an array.

Sunday, August 14, 2022
 
voddy
 
5

The named import's symbol will have an associated "aliased symbol", which represents the declaration. So to get the variable declaration's symbol you can use the TypeChecker#getAliasedSymbol method, then from that get the declaration.

For example:

const barNamedImportSymbol = typeChecker.getSymbolAtLocation(barNamedImport.name)!;
const barSymbol = typeChecker.getAliasedSymbol(barNamedImportSymbol);
const barDeclaration = barSymbol.declarations[0] as ts.VariableDeclaration;

console.log(barDeclaration.getText(barFile)); // outputs `bar = 3`

The import declaration's named import has a separate symbol because that's the symbol specific to the "foo.ts" file.

Update: Getting symbol of file referenced in module specifier

To get the symbol of a file referenced in an import or export declarations module specifier, you can get the symbol of the module specifier node:

const otherFileSymbol = typeChecker.getSymbolAtLocation(importDeclaration.moduleSpecifier)!;

From there, you can check its exports for a certain name:

const barSymbol = otherFileSymbol.exports!.get(ts.escapeLeadingUnderscores("bar"))!;
// outputs: export { bar } from "./baz"; in second example above
console.log(barSymbol.declarations[0].parent.parent.getText());
Tuesday, December 6, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :