php get all classes by namespace
Php get all classes by namespace
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Here is an example of the three kinds of syntax in actual code:
namespace Foo \ Bar \ subnamespace ;
const FOO = 1 ;
function foo () <>
class foo
<
static function staticmethod () <>
>
?>
namespace Foo \ Bar ;
include ‘file1.php’ ;
const FOO = 2 ;
function foo () <>
class foo
<
static function staticmethod () <>
>
/* Unqualified name */
foo (); // resolves to function Foo\Bar\foo
foo :: staticmethod (); // resolves to class Foo\Bar\foo, method staticmethod
echo FOO ; // resolves to constant Foo\Bar\FOO
/* Qualified name */
subnamespace \ foo (); // resolves to function Foo\Bar\subnamespace\foo
subnamespace \ foo :: staticmethod (); // resolves to class Foo\Bar\subnamespace\foo,
// method staticmethod
echo subnamespace \ FOO ; // resolves to constant Foo\Bar\subnamespace\FOO
/* Fully qualified name */
\ Foo \ Bar \ foo (); // resolves to function Foo\Bar\foo
\ Foo \ Bar \ foo :: staticmethod (); // resolves to class Foo\Bar\foo, method staticmethod
echo \ Foo \ Bar \ FOO ; // resolves to constant Foo\Bar\FOO
?>
Example #1 Accessing global classes, functions and constants from within a namespace
function strlen () <>
const INI_ALL = 3 ;
class Exception <>
$a = \ strlen ( ‘hi’ ); // calls global function strlen
$b = \ INI_ALL ; // accesses global constant INI_ALL
$c = new \ Exception ( ‘error’ ); // instantiates global class Exception
?>
How to get all class names inside a particular namespace?
I want to get all classes inside a namespace. I have something like this:
I tried get_declared_classes() inside getAllClasses() but MyClass1 and MyClass2 were not in the list.
How could I do that?
15 Answers 15
The generic approach would be to get all fully qualified classnames (class with full namespace) in your project, and then filter by the wanted namespace.
PHP offers some native functions to get those classes (get_declared_classes, etc), but they won’t be able to find classes that have not been loaded (include / require), therefore it won’t work as expected with autoloaders (like Composer for example). This is a major issue as the usage of autoloaders is very common.
So your last resort is to find all PHP files by yourself and parse them to extract their namespace and class:
If you follow PSR 0 or PSR 4 standards (your directory tree reflects your namespace), you don’t have to filter anything: just give the path that corresponds to the namespace you want.
That package can be found here: haydenpierce/class-finder.
See more info in the README file.
I wasn’t happy with any of the solutions here so I ended up building my class to handle this. This solution requires that you are:
The contiguous sub-namespace names after the «namespace prefix» correspond to a subdirectory within a «base directory», in which the namespace separators represent directory separators. The subdirectory name MUST match the case of the sub-namespace names.
Pretty interesting that there does not seem to be any reflection method that does that for you. However I came up with a little class that is capable of reading namespace information.
In order to do so, you have to traverse trough all defined classes. Then we get the namespace of that class and store it into an array along with the classname itself.
The output will be:
array(2) < [0]=>string(17) «ClassTwo\ClassTwo» [1]=> string(20) «ClassTwo\ClassTwoNew» >
Of course everything besides the NameSpaceFinder class itself if assembled quick and dirty. So feel free to clean up the include mess by using autoloading.
Quite a few interesting answers above, some actually peculiarly complex for the proposed task.
To add a different flavor to the possibilities, here a quick and easy non-optimized function to do what you ask using the most basic techniques and common statements I could think of:
I’ve written this function to assume you are not adding the last «trailing slash» ( \ ) on the namespace, so you won’t have to double it to escape it. 😉
Please notice this function is only an example and has many flaws. Based on the example above, if you use ‘ namespace\sub ‘ and ‘ namespace\sub\deep ‘ exists, the function will return all classes found in both namespaces (behaving as if it was recursive). However, it would be simple to adjust and expand this function for much more than that, mostly requiring a couple of tweaks in the foreach block.
It may not be the pinnacle of the code-art-nouveau, but at least it does what was proposed and should be simple enough to be self-explanatory.
I hope it helps pave the way for you to achieve what you are looking for.
PHP Namespace
Summary: in this tutorial, you’ll learn about PHP namespaces, how to define classes that belong to a namespace, and how to use namespaces.
Why namespaces
When your project grows in complexity, you’ll need to integrate the code from others. Sooner or later, you’ll find that your code has different classes with the same name. This problem is known as name collision.
To resolve it, you can use namespaces. PHP supported namespaces since version 5.3.
What is a namespace
It’s easier to understand namespaces by analogy to the directory structure in a filesystem.
A directory stores related files, which is similar to a namespace that groups related classes.
A directory doesn’t allow you to have two files with the same name. However, you can have files with the same names in different directories. Likewise, namespaces mimic the same principle.
By definition, namespaces provide you with a way to group related classes and help you avoid any potential name collisions.
Namespaces are not limited to group classes. They can group other identifiers, including functions, constants, variables, etc.
Set up a directory structure
First, create a project directory, e.g., store and create a new index.php file in the directory.
Second, create src directory in the project directory and Model directory in the src directory.
Third, create a new file called Customer.php in the Model directory with the following code:
The directory looks like the following:
Define a namespace
To define a namespace, you place the namespace keyword followed by a name at the very top of the page. The following example gives the Customer class with a namespace Store\Model :
Use a class that belongs to a namespace
Since the Customer class now is namespaced, you need to use the fully qualified name that includes the namespace like this:
Now, it should work properly.
Import a namespace
To avoid using the fully qualified names from a namespace, you can import the namespace with the use operator like this:
Import a class from a namespace
PHP allows you to import a class from a namespace instead of importing the namespace. For example:
In this example, we use the use operator to import the Customer class from the Store\Model namespace. Therefore, we don’t have to prefix the class name with the namespace.
Import multiple classes from a namespace
First, create a new file called Product.php in the src/Model directory:
For demonstration purposes, the Product class is empty. Now, the directory structure looks like the following:
When the number of imported classes grows, your code will become more verbose. So instead of importing each individual class, you can import all the classes using a single statement:
Alias classes from a namespace
First, create a new directory called Database under the project directory and place a new file Logger.php in the Database directory with the following code:
Second, create a new directory Utils under the project directory and create a new Logger.php in the Utils directory.
Now, you have two classes with the same name in different namespaces:
Third, import Logger classes from both namespaces Store\Utils and Database\Logger into the index.php file:
PHP raises the following error:
To avoid this, you can just import the namespaces:
Or you can give a class an alias when importing it:
The following example assigns the DatabaseLogger class an alias to the Store\Database\Logger class:
Use classes from the global namespace
To use global classes such as built-in classes or user-defined classes without a namespace, you need to precede the name of such classes with a backslash ( \ ).
The following example shows how to use the built-in DateTime class in the App namespace:
PHP – get all class names inside a particular namespace
Posted by: admin November 29, 2017 Leave a comment
I want to get all classes inside a namespace. I have something like this:
I tried get_declared_classes() inside getAllClasses() but MyClass1 and MyClass2 were not in the list.
How could I do that?
The generic approach would be to get all fully qualified classnames (class with full namespace) in your project, and then filter by the wanted namespace.
PHP offers some native functions to get those classes (get_declared_classes, etc), but they won’t be able to find classes that have not been loaded (include / require), therefore it won’t work as expected with autoloaders (like Composer for example).
This is a major issue as the usage of autoloaders is very common.
So your last resort is to find all PHP files by yourself and parse them to extract their namespace and class:
If you follow PSR 0 or PSR 4 standards (your directory tree reflects your namespace), you don’t have to filter anything: just give the path that corresponds to the namespace you want.
I wasn’t happy with any of the solutions here so I ended up building my class to handle this. This solution requires that you are:
The contiguous sub-namespace names after the “namespace prefix”
correspond to a subdirectory within a “base directory”, in which the
namespace separators represent directory separators. The subdirectory
name MUST match the case of the sub-namespace names.
Pretty interesting that there does not seem to be any reflection method that does that for you. However I came up with a little class that is capable of reading namespace information.
In order to do so, you have to traverse trough all defined classes. Then we get the namespace of that class and store it into an array along with the classname itself.
The output will be:
array(2) < [0]=>string(17) «ClassTwo\ClassTwo» [1]=> string(20) «ClassTwo\ClassTwoNew» >
Of course everything besides the NameSpaceFinder class itself if assembled quick and dirty. So feel free to clean up the include mess by using autoloading.
Locate Classes
A class can be localized in the file system by its name and its namespace, like the autoloader does. In the normal case the namespace should tell the relative path to the class files. The include paths are the starting points of the relative paths. The function get_include_path() returns a list of include paths in one string. Each include path can be tested, whether there exists a relative path which matches the namespace. If the matching path is found, you will know the location of the class files.
Get Class Names
Sample Code
Here is a sample code to get all class names of the namespace foo\bar as a string array:
I am going to give an example which is actually being used in our Laravel 5 app but can be used almost everywhere. The example returns class names with the namespace which can be easily taken out, if not required.
Legend
I think a lot of people might have a problem like this, so I relied on the answers from @hpierce and @loГЇc-faugeron to solve this problem.
With the class described below, you can have all classes within a namespace or they respect a certain term.
In this case, you must use Composer to perform class autoloading. Using the ClassMap available on it, the solution is simplified.
Otherwise I think You will have to deal with some reflection methods.
You can use get_declared_classes but with a little additional work.
So first you get all declared classes and then check which of them starts with your namespace.
Related Posts
php – htmlentities() vs. htmlspecialchars()
Questions: What are the differences between htmlspecialchars() and htmlentities(). When should I use one or the other? How to&Answers: From the PHP documentation for htmlentities: This function is.
php – Show a number to two decimal places
How do I catch a PHP Fatal Error
Questions: I can use set_error_handler() to catch most PHP errors, but it doesn’t work for fatal (E_ERROR) errors, such as calling a function that doesn’t exist. Is there another way to ca.
is it possible to get list of defined namespaces
I was wondering if there is a way in php 5.3+ to get a list of defined namespaces within an application. so
if file 1 has namespace FOO and file 2 has namespace BAR
Now if i include file 1 and file 2 in file 3 id like to know with some sort of function call that namespace FOO and BAR are loaded.
I want to achieve this to be sure an module in my application is loaded before checking if the class exists ( with is_callable ).
If this is not possible i’d like to know if there is a function to check if a specific namespace is defined, something like is_namespace().
Hope you get the idea. and what i’m trying to achieve
2 Answers 2
In the simplest case, you can use this to find a matching namespace from all declared class names:
Another example, the following script produces a hierarchical array structure of declared namespaces:
I know this question already has an answer, but I wanted to provide a more realistic solution to what I believe your problem is. Had I had more time yesterday when I made my comment I would have posted this. Sorry that I didn’t.
It sounds like OP has a module system that he needs to know if a particular module is loaded prior to allowing a call to it.
First, I’d like to say that using namespaces simply to declare modules active is, IMO, abusing what they are for. If you follow the purpose of namespacing to the letter, your structure might look more like this:
Now, let’s get into making a module system that registers itself on load.
Now, in each module you’d need to call this register function when the file is loaded. There are a couple of ways to do this. The first is to have some code in your module’s namespace that run on load similar to typical proceedural code:
The above would mean code duplication though. You might also use autoload for this instead, that way the «registering» code is all in one place. Here’s a very basic concept of doing that:
Another possible way of doing this would be to define an interface for modules with a specific function for registering when the module is initialized. This, however, means the module needs to be loaded first and might cause it’s own issues depending on your needs.