php get object class name
Get class name from file
I have a php file which contains only one class. how can I know what class is there by knowing the filename? I know I can do something with regexp matching but is there a standard php way? (the file is already included in the page that is trying to figure out the class name).
11 Answers 11
There are multiple possible solutions to this problem, each with their advantages and disadvantages. Here they are, it’s up to know to decide which one you want.
Tokenizer
This method uses the tokenizer and reads parts of the file until it finds a class definition.
Advantages
Disadvantages
Code
Regular expressions
Use regular expressions to parse the beginning of the file, until a class definition is found.
Advantages
Disadvantages
Code
Note: The regex can probably be improved, but no regex alone can do this perfectly.
Get list of declared classes
This method uses get_declared_classes() and look for the first class defined after an include.
Advantages
Disadvantages
Code
Note: You cannot simply do end() as others suggested. If the class includes another class, you will get a wrong result.
This is the Tokenizer solution, modified to include a $namespace variable containing the class namespace, if applicable:
Say you have this class:
. or the alternative syntax:
You should have the following result:
You could also use the above to detect the namespace a file declares, regardless of it containing a class or not.
How do I get an object’s unqualified (short) class name?
How do I check the class of an object within the PHP name spaced environment without specifying the full namespaced class.
For example suppose I had an object library/Entity/Contract/Name.
The following code does not work as get_class returns the full namespaced class.
The namespace magic keyword returns the current namespace, which is no use if the tested object has another namespace.
I could simply specify the full classname with namespaces, but this seems to lock in the structure of the code. Also not of much use if I wanted to change the namespace dynamically.
Can anyone think of an efficient way to do this. I guess one option is regex.
22 Answers 22
You can do this with reflection. Specifically, you can use the ReflectionClass::getShortName method, which gets the name of the class without its namespace.
First, you need to build a ReflectionClass instance, and then call the getShortName method of that instance:
(new \ReflectionClass($obj))->getShortName(); is the best solution with regards to performance.
I was curious which of the provided solutions is the fastest, so I’ve put together a little test.
Results
Code
The results actually surprised me. I thought the explode solution would be the fastest way to go.
I added substr to the test of https://stackoverflow.com/a/25472778/2386943 and that’s the fastet way I could test (CentOS PHP 5.3.3, Ubuntu PHP 5.5.9) both with an i5.
Results
Code
==UPDATE==
As mentioned in the comments by @MrBandersnatch there is even a faster way to do this:
Here are the updated test results with «SubstringStrChr» (saves up to about 0.001 s):
Here is a more easier way of doing this if you are using Laravel PHP framework :
To get the short name as an one-liner (since PHP 5.4):
It is a clean approach and reasonable fast.
I found myself in a unique situation where instanceof could not be used (specifically namespaced traits) and I needed the short name in the most efficient way possible so I’ve done a little benchmark of my own. It includes all the different methods & variations from the answers in this question.
A list of the of the entire result is here but here are the highlights:
A simplified table of results, speed is measured compared to the slowest method:
get_class
(PHP 4, PHP 5, PHP 7, PHP 8)
get_class — Returns the name of the class of an object
Description
Parameters
The tested object. This parameter may be omitted when inside a class.
Note: Explicitly passing null as the object is no longer allowed as of PHP 7.2.0. The parameter is still optional and calling get_class() without a parameter from inside a class will work, but passing null now emits an E_WARNING notice.
Return Values
Returns the name of the class of which object is an instance. Returns false if object is not an object.
If object is omitted when inside a class, the name of that class is returned.
If the object is an instance of a class which exists in a namespace, the qualified namespaced name of that class is returned.
Errors/Exceptions
If get_class() is called with anything other than an object, an E_WARNING level error is raised.
Changelog
Examples
Example #1 Using get_class()
// create an object
$bar = new foo ();
The above example will output:
Example #2 Using get_class() in superclass
class foo extends bar <
>
The above example will output:
Example #3 Using get_class() with namespaced classes
namespace Foo \ Bar ;
class Baz <
public function __construct ()
<
$baz = new \ Foo \ Bar \ Baz ;
The above example will output:
See Also
User Contributed Notes 36 notes
::class
fully qualified class name, instead of get_class
namespace my \ library \ mvc ;
print Dispatcher ::class; // FQN == my\library\mvc\Dispatcher
$disp = new Dispatcher ;
(For reference, here’s the debug code used. c() is a benchmarking function that runs each closure run 10,000 times.)
If you are using namespaces this function will return the name of the class including the namespace, so watch out if your code does any checks for this. Ex:
class Foo
<
public function __construct ()
<
echo «Foo» ;
>
>
People seem to mix up what __METHOD__, get_class($obj) and get_class() do, related to class inheritance.
Here’s a good example that should fix that for ever:
class Bar extends Foo <
$foo = new Foo ();
$bar = new Bar ();
$quux = new Quux ();
—doMethod—
Foo::doMethod
Foo::doMethod
Quux::doMethod
—doGetClassThis—
Foo::doThat
Bar::doThat
Quux::doThat
—doGetClass—
Foo::doThat
Foo::doThat
Quux::doThat
In Perl (and some other languages) you can call some methods in both object and class (aka static) context. I made such a method for one of my classes in PHP5, but found out that static methods in PHP5 do not ‘know’ the name of the calling subclass’, so I use a backtrace to determine it. I don’t like hacks like this, but as long as PHP doesn’t have an alternative, this is what has to be done:
Simplest way how to gets Class without namespace
namespace a \ b \ c \ d \ e \ f ;
echo new Foo (); // prints Foo
?>
Need a quick way to parse the name of a class when it’s namespaced? Try this:
/**
* Obtains an object class name without namespaces
*/
function get_real_class($obj) <
$classname = get_class($obj);
With regard to getting the class name from a namespaced class name, then using basename() seems to do the trick quite nicely.
namespace Foo \ Bar ;
class Snafu extends Baz
<
>
__CLASS__ Foo\Bar\Baz Baz
get_called_class Foo\Bar\Snafu Snafu
The code in my previous comment was not completely correct. I think this one is.
/**
* Returns the classname of the child class extending this class
*
* @return string The class name
*/
private static function getClass() <
$implementing_class = static::$__CLASS__;
$original_class = __CLASS__;
There are discussions below regarding how to create a singleton that allows subclassing. It seems with get_called_class there is now a cleaner solution than what is discussed below, that does not require overriding a method per subclass.
private function __construct () <
// Singleton
>
>
class MySubclass extends MySuperclass <
>
Although you can call a class’s static methods from an instance of the class as though they were object instance methods, it’s nice to know that, since classes are represented in PHP code by their names as strings, the same thing goes for the return value of get_class():
If you want the path to an file if you have i file structure like this
and foo() in foo.php extends controller() in controller.php like this
namespace system \ modules \ foo ;
class foo extends \ system \ libs \ controller <
public function __construct () <
parent :: __construct ();
>
>
?>
and you want to know the path to foo.php in controller() this may help you
namespace system \ libs ;
well, if you call get_class() on an aliased class, you will get the original class name
Attempting various singleton base class methods described on this page, I have created a base class and bridge function that allows it to work without get_called_class() if it’s not available. Unlike other methods listed here, I chose not to prevent use of __construct() or __clone().
default: throw new Exception ( «Unknown backtrace method type» );
>
>
>
class B extends Singleton <
>
class C extends Singleton <
>
Method for pulling the name of a class with namespaces pre-stripped.
namespace testme \ here ;
public function test ()
<
return get_class_name ( get_class ());
>
>
As noted in bug #30934 (which is not actually a bug but a consequence of a design decision), the «self» keyword is bound at compile time. Amongst other things, this means that in base class methods, any use of the «self» keyword will refer to that base class regardless of the actual (derived) class on which the method was invoked. This becomes problematic when attempting to call an overridden static method from within an inherited method in a derived class. For example:
public static function classDisplayName ()
<
return ‘Base Class’ ;
>
public static function classDisplayName ()
<
return ‘Derived Class’ ;
>
>
However, assuming compile-time binding (where the keyword «self» refers to the class in which the method is defined), which is how php works, the output would be:
The oddity here is that «$this» is bound at runtime to the actual class of the object (obviously) but «self» is bound at compile-time, which seems counter-intuitive to me. «self» is ALWAYS a synonym for the name of the class in which it is written, which the programmer knows so s/he can just use the class name; what the programmer cannot know is the name of the actual class on which the method was invoked (because the method could be invoked on a derived class), which it seems to me is something for which «self» ought to be useful.
However, questions about design decisions aside, the problem still exists of how to achieve behaviour similar to «self» being bound at runtime, so that both static and non-static methods invoked on or from within a derived class act on that derived class. The get_class() function can be used to emulate the functionality of runtime binding for the «self» keyword for static methods:
public static function classDisplayName ()
<
return ‘Base Class’ ;
>
public static function classDisplayName ()
<
return ‘Derived Class’ ;
>
>
I realise that some people might respond «why don’t use just just the class name with ‘ Class’ appended instead of the classDisplayName() method», which is to miss the point. The point is not the actual strings returned but the concept of wanting to use the real class for an overridden static method from within an inherited non-static method. The above is just a simplified version of a real-world problem that was too complex to use as an example.
Apologies if this has been mentioned before.
Функции работы с классами и объектами
Содержание
User Contributed Notes 19 notes
[Editor’s note: If you are trying to do overriding, then you can just interrogate (perhaps in the method itself) about what class (get_class()) the object belongs to, or if it is a subclass of a particular root class.
You can alway refer to the parent overriden method, see the «Classes and Objects» page of the manual and comments/editor’s notes therein.]
There is no function to determine if a member belongs to a base class or current class eg:
class foo <
function foo () < >
function a () < >
>
class bar extends foo <
function bar () < >
function a () < >
>
lala = new Bar ();
?>
——————
how do we find programmatically if member a now belongs to class Bar or Foo.
To pillepop2003 at yahoo dot de:
I have the same issue. I have a base class that manages database tasks for a number of child classes. One of the functions in the base class is a find() method that returns instances of the child classes. Since find() is usually called as a static method, it needs to know the name of the child class. As you’ve found, this appears to be impossible to get in an easy fashion.
The only way I’ve found to get the child class name is to use the debug_traceback() function. This requires me to have a find() method in every child class, but it does work.
function find () <
return parent :: find ();
>
>
function find () <
return parent :: find ();
>
>
FYI: if you want to split your class into manageble chunks, what means different files for you, you can put you functoins into includes, and make include() have a return value. Like this:
And your included file:
Then your function call will be:
$instance = new Some_class ();
$instance->add_value (3);
And this will return
6
hopefully 😛
Keep in mind though, that the scope in the included file will be identical to the scope the function ‘add_value’ has.
And if you want to return the outcome, you should also have a return statement made in your include as well.
Something I found out just now that comes in very handy for my current project:
it is possible to have a class override itself in any method ( including the constructor ) like this:
in this case assuming that class b is already defined and also has the method ha ( )
note that the code after the statement to override itself is still executed but now applies to the new class
i did not find any information about this behaviour anywhere, so i have no clue wether this is supposed to be like this and if it might change. but it opens a few possibilities in flexible scripting!!
Re: Looking for an uninstantiated class
Why would I do this? Because I have my class layouts the same as their respective tables; the factory then selects the data (making sure that the variables match) and plugs in the data. (I’ve left out the actual code to do the selection/insertion).
To pillepop2003 at yahoo dot de:
It seems to me if there really is no nice way to get the class name in an un-instanciated class, there is a workaround in PHP5 though using static/class variables.
?>
However, you’ll need to have at least instanciated an object of the class myFooExtended before calling getClassName or introduce some other initialization (the class variable will need to be set at some point to __CLASS__ in the sub-class).
If you want to be able to call an instance of a class from within another class, all you need to do is store a reference to the external class as a property of the local class (can use the constructor to pass this to the class), then call the external method like this:
or if the double ‘->’ is too freaky for you, how about:
This is handy if you write something like a general SQL class that you want member functions in other classes to be able to use, but want to keep namespaces separate. Hope that helps someone.
I wanted to dynamically choose an extender for a class. This took awhile of playing with it but I came up with a solution. Note that I can’t verify how safe it is, but it appears to work for me. Perhaps someone else can shed light on the details:
Practical application: I have a database abstraction system that has individual classes for mysql, pgsql, et al. I want to be able to create a global db class that extends one of the individual db classes depending on the application configuration.
I know that there are probably much better ways of doing this but I haven’t reached that level when it comes to classes.
to covertka at muohio dot edu and pillepop2003 at yahoo dot de:
There’s a much easier solution to getting a class’ name for working with a factory function. Let’s assume you’re doing something like this:
?>
Now, consider the named parameter idiom and remember that PHP uses hashes for everything; as a result make the following changes:
?>
Nice ‘n simple. It seems that what the original poster wanted was something like C++ static data members; unfortunately as PHP4 has no static variables at all, there would need to be significant language change to support static-like behavior. If you move to PHP5, the static keyword solves your problem cleanly.
To access an object member with an illegal character in the name, use this syntax:
This is particularly relevant with the dynamically-generated classes used by, for instance, database objects and the SoapClient class.
Subject: using «sql_calc_found_rows» in a MySQL query while exploiting result in a PHP db class object.
There is a nice function in MySQL that allows to know how many records would have been returned if no «where» clause were set : SQL_CALC_FOUND_ROWS.
If you have create a db object to collect the returned lines, you will be a little perplex when trying to call the result of this function.
Then, the only way to get the right result seems to be the use of a class function, like :
A small function that allows finding all references to the object. Written in 3 minutes and may be buggy (for ex pass object as reference in some places?)
Why do u want to know the classname of an non-existant object?
The only possible explanation for this question seems to me u want to know the class before u instantiate the object. Well, this is of no use since u always instantiate a class of ur choice.
When the class is instantiated into an object u can find the class of the object by means of get_class(). This is all u need. In case of inheritance u can use get_class($this) to get the class of the instantiated object. Now u can differentiate according to which class the object belongs to.
$object1 = new A ();
$object2 = new B ();
?>
When u run this code-snippet the output will be:
Object is an instance of class A which is the parent-class.
Object is an instance of class B which is the child-class.
We have an array with many objects in a style like
Because there is no function in php api, we made the following function.
Warning: function is very slow and should only be called if it’s necessary for debugging reasons:
// clean the output-buffer
ob_end_clean ();
// cache the last match
$lastMatch = array();
// the return value
$return = array();
?>
I know, it’s not that elegant but I hope it’s useful for a few people.
get_class
get_class — Возвращает имя класса, к которому принадлежит объект
Описание
Список параметров
Тестируемый объект. Внутри класса этот параметр может быть опущен.
Возвращаемые значения
Если параметр object опущен внутри класса, будет возвращено имя этого класса.
Если параметр object является экземпляром класса, существующего в пространстве имен, то будет возвращено полное имя с указанием пространства имен.
Ошибки
Список изменений
Версия | Описание |
---|---|
7.2.0 | До этой версии значением по умолчанию для object было null с тем же эффектом, что и отсутствие передачи значения. Теперь null был удален как значение по умолчанию для object и больше не является допустимым значением. |
Примеры
Пример #1 Использование get_class()
// создание объекта
$bar = new foo ();
Результат выполнения данного примера:
Пример #2 Использование get_class() в родительском классе
class foo extends bar <
>
Результат выполнения данного примера:
Пример #3 Использование get_class() с классами в пространствах имен
namespace Foo \ Bar ;
class Baz <
public function __construct ()
<
$baz = new \ Foo \ Bar \ Baz ;
Результат выполнения данного примера: