- PHP | get_declared_classes() Function
- PHP | get_declared_classes() Function
- How do I find all the classes used in a PHP file?
- Get functions and classes defined in file?
- Identifying between PHP Internal Classes and User-defined Classes
- get_declared_classes
- Changelog
- Examples
- See Also
- User Contributed Notes 9 notes
PHP | get_declared_classes() Function
How can I extend this code to find any additional instances of PHP classes like mentioned above? http://www.php.net/manual/en/tokens.php http://westhoffswelt.de/blog/class_dependency_graph_generation_update.html http://phpqatools.org/ Solution 1: Parsing and then interpreting PHP code is not something that can be solved well using a regex. You would need a something much more clever, like a state machine, that can actually understand things like scope, class names, inheritance etc to be able to do what you want.
PHP | get_declared_classes() Function
The get_declared_classes() function is an inbuilt function in PHP which is used to return an array with the name of the defined classes. The user array containing the list of all the system-defined(for example, PDO, XML reader, etc) and user-defined classes in the present script. No parameters are given to this function.
Array ( [0] => stdClass [1] => Exception [2] => ErrorException [3] => Error [4] => ParseError . . . [155] => Ds\PriorityQueue [156] => Ds\Pair [157] => gfg [158] => gfg1 )
Sorting the list: Finding a particular class in such a big list can be difficult. But it can be easier if the list is sorted alphabetically. It can be sorted through the function sort() .
Array ( [0] => AppendIterator [1] => ArithmeticError [2] => ArrayIterator [3] => ArrayObject [4] => AssertionError . . . [152] => XMLWriter [153] => __PHP_Incomplete_Class [154] => finfo [155] => php_user_filter [156] => stdClass )
Reference: https://www.php.net/manual/en/function.get-declared-classes.php
Can I get CONST’s defined on a PHP class?, You can do this using reflection. Search for «Print class constants» on that page to see an example. · Using Reflection, and a ReflectionClass on
How do I find all the classes used in a PHP file?
I am trying to use the tokenizer to scan a file to find all the defined classes, anything they extend, any created instances, and anytime they were statically invoked.
$token) < if(is_array($token)) < if(isset($tokens[$i - 2][0], $tokens[$i - 1][0])) < // new [class] if ($tokens[$i - 2][0] == T_NEW AND $tokens[$i - 1][0] == T_WHITESPACE) < if($tokens[$i][0] == T_STRING) < $used_classes[$token[1]] = TRUE; // new $variable() >elseif($tokens[$i][0] == T_VARIABLE) < // @todo, this is really broken. However, do best to look for the assignment if(preg_match('~\$var\s*=\s*([\'"])((?:(?!\1).)*)\1~', $text, $match)) < if(empty($extension_classes[$match[2]])) < $used_classes[$match[2]] = TRUE; >> elseif($token[1] !== '$this') < $variable_classes[$token[1]] = TRUE; >> > // class [class] if ($tokens[$i - 2][0] == T_CLASS AND $tokens[$i - 1][0] == T_WHITESPACE) < if($tokens[$i][0] == T_STRING) < $defined_classes[$token[1]] = TRUE; >> // @todo: find more classes \/ // class [classname] extends [class] . // [class]::method(). > > >
How can I extend this code to find any additional instances of PHP classes like mentioned above?
- http://www.php.net/manual/en/tokens.php
- http://westhoffswelt.de/blog/class_dependency_graph_generation_update.html
- http://phpqatools.org/
Parsing and then interpreting PHP code is not something that can be solved well using a regex. You would need a something much more clever, like a state machine, that can actually understand things like scope, class names, inheritance etc to be able to do what you want.
It just so happens, that I happen to have written a PHP-to-Javascript converter based on a state-machine that will almost do most of what you want to do:
Yes, all the classes create a ClassScope with all their variables listed and their methods are created as FunctionScope’s, so you can tell which methods a class has.
Yes, every class has it’s parent classes listed in ClassScope->$parentClasses
Nope, but wouldn’t be hard to add extra code to record these.
anytime they were statically invoked.
Nope — but that actually could be done with a regex.
Although it doesn’t exactly solve your problem, the project as it stands would get you 95% of the way towards what you want to do, which would save a couple weeks work.
Inclued is probably worth looking into here, though I don’t think it will provide you with any data beyond which files/classes were included and how many times.
I don’t think you can do this by just analyzing tokens.
You need to know, for any class name, what actual definition it represents, including any inheritance relations, and whether it has been used in your code to implement an interface. The class/interface definition may be in another file; that file may be included under some condition. You may have the same class name defined differently in different files. So in general you need to to process all the files that comprise your system at once.
What you need as a foundation is a tool that parses PHP and builds up real symbol tables. You might be able to compute your result from that. (Such a tool analyzes tokens as a starting place, but it is far more work than trivial token scanning).
It looks like if you just load the code, you can then use the built-in Reflection API (reflectionclass::_construct(), etc.) to examine each class.
To get the classes themselves, use the built-in get_declared_classes().
(Note: I have not tried this, so YMMV.)
How resolve PHP class defined in another folder, how does PHP find a class when the class is defined in a sibling folder of the running .php file? The php file I am running is located in
Get functions and classes defined in file?
I’m looping over all the files in a directory. Now I want to get all the functions and classes defined in each of them. From there, I can examine them further using the ReflectionClass. I can’t figure out how to get all the functions and classes defined in a file though.
ReflectionExtension looks the closest to what I want, except my files aren’t part of an extension. Is there some class or function I’m overlooking?
Great question. get_declared_classes and get_defined_functions could be a good starting point. You would have to take note of what classes / functions are already defined when trying to determine what’s in a given file.
Also, not sure what your end goal is here, but tools such as PHP Depend or PHP Mess Detector may do something similar to what you want. I’d recommend checking them out as well.
This is the best I could come up with (courtesy):
function trimds($s) < return rtrim($s,DIRECTORY_SEPARATOR); >function joinpaths() < return implode(DIRECTORY_SEPARATOR, array_map('trimds', func_get_args())); >$project_dir = '/path/to/project/'; $ds = array($project_dir); $classes = array(); while(!empty($ds)) < $dir = array_pop($ds); if(($dh=opendir($dir))!==false) < while(($file=readdir($dh))!==false) < if($file[0]==='.') continue; $path = joinpaths($dir,$file); if(is_dir($path)) < $ds[] = $path; >else < $contents = file_get_contents($path); $tokens = token_get_all($contents); for($i=0; $i> > > > else < echo "ERROR: Could not open directory '$dir'\n"; >> print_r($classes);
Wish I didn’t have to parse out the files and loop over all the tokens like this.
Forgot the former solutions prevents me from using reflection as I wanted. New solution:
$project_dir = '/path/to/project/'; $ds = array($project_dir); while(!empty($ds)) < $dir = array_pop($ds); if(($dh=opendir($dir))!==false) < while(($file=readdir($dh))!==false) < if($file[0]==='.') continue; $path = joinpaths($dir,$file); if(is_dir($path)) < $ds[] = $path; >else < try< include_once $path; >catch(Exception $e) < echo 'EXCEPTION: '.$e->getMessage().PHP_EOL; > > > > else < echo "ERROR: Could not open directory '$dir'\n"; >> foreach(get_declared_classes() as $c) < $class = new ReflectionClass($c); $methods = $class->getMethods(); foreach($methods as $m) < $dc = $m->getDocComment(); if($dc !== false) < echo $class->getName().'::'.$m->getName().PHP_EOL; echo $dc.PHP_EOL; > > >
Define a global variable in a php class, Do you want this data to persist across multiple calls to the object or multiple instantiations of the class? · it is better to do that in your
Identifying between PHP Internal Classes and User-defined Classes
I’ve been trawling through the PHP docs trying to identify if there is any method that will allow me to differentiate between instances of a built-in class (such as DateTime or PDO) and User-defined Classes, but without any success.
The only approach that I have found so far is to try and bind a closure to the instance. When doing this with a built-in class, it displays a warning (yuk) and returns a null.
$targetObject = new DateTime(); $closure = function(); $test = @$closure->bindTo($targetObject, get_class($targetObject)); if ($test === false) < throw new Exception('General failure'); >elseif ($test === null)
Is anybody aware of a cleaner approach to this problem?
Take a look at the reflection API. Manual
Class variables holding a function in PHP, PHP doesn’t have first class functions. In JavaScript if you returned a function you could do this: myFunctionThatReturnsAFunction()(1,2)
get_declared_classes
Returns an array of the names of the declared classes in the current script.
Note:
Note that depending on what extensions you have compiled or loaded into PHP, additional classes could be present. This means that you will not be able to define your own classes using these names. There is a list of predefined classes in the Predefined Classes section of the appendices.
Changelog
Version | Description |
---|---|
7.4.0 | Previously get_declared_classes() always returned parent classes before child classes. This is no longer the case. No particular order is guaranteed for the get_declared_classes() return value. |
Examples
Example #1 get_declared_classes() example
The above example will output something similar to:
Array ( [0] => stdClass [1] => __PHP_Incomplete_Class [2] => Directory )
See Also
- class_exists() — Checks if the class has been defined
- get_declared_interfaces() — Returns an array of all declared interfaces
- get_defined_functions() — Returns an array of all 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.
- Classes/Object Functions
- 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