How to print object name in php?

So I got this source code

//get activated bundles
$bundle_list = new AutoRouter('dev',true);
$bundle_list = $bundle_list->getActivatedBundles(); 

for($a =0; $a < sizeof($bundle_list); $a++)
{
    var_dump($bundle_list[$a]);
}

The dump returns several objects like this

object(Symfony\Bundle\FrameworkBundle\FrameworkBundle)[38]
  protected 'name' => null
  protected 'extension' => null
  protected 'path' => null
  protected 'container' => null

object(Symfony\Bundle\SecurityBundle\SecurityBundle)[41]
  protected 'name' => null
  protected 'extension' => null
  protected 'path' => null
  protected 'container' => null

object(Symfony\Bundle\TwigBundle\TwigBundle)[40]
  protected 'name' => null
  protected 'extension' => null
  protected 'path' => null
  protected 'container' => null

I need to extract the object names as string like this:

(string) "Symfony\Bundle\FrameworkBundle\FrameworkBundle"
(string) "Symfony\Bundle\SecurityBundle\SecurityBundle"
(string) "Symfony\Bundle\TwigBundle\TwigBundle"

Something like

for($a =0; $a < sizeof($bundle_list); $a++)
{
    var_dump((string) $bundle_list[$a]);
}

(PHP 4, PHP 5, PHP 7, PHP 8)

get_classReturns the name of the class of an object

Description

get_class(object $object = ?): string

Parameters

object

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 and emits an E_WARNING. As of PHP 8.0.0, a TypeError is emitted when null is used.

Return Values

Returns the name of the class of which object is an instance.

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, TypeError is raised. Prior to PHP 8.0.0, an E_WARNING level error was raised.

If get_class() is called with no arguments from outside a class, Error is raised. Prior to PHP 8.0.0, an E_WARNING level error was raised.

Changelog

VersionDescription
8.0.0 Calling this function from outside a class, without any arguments, will trigger an Error. Previously, an E_WARNING was raised and the function returned false.
7.2.0 Prior to this version the default value for object was null and it had the same effect as not passing any value. Now null has been removed as the default value for object, and is no longer a valid input.

Examples

Example #1 Using get_class()

class foo {
    function 
name()
    {
        echo 
"My name is " get_class($this) , "\n";
    }
}
// create an object
$bar = new foo();// external call
echo "Its name is " get_class($bar) , "\n";// internal call
$bar->name();?>

The above example will output:

Its name is foo
My name is foo

Example #2 Using get_class() in superclass

abstract class bar {
    public function 
__construct()
    {
        
var_dump(get_class($this));
        
var_dump(get_class());
    }
}

class

foo extends bar {
}

new

foo;?>

The above example will output:

string(3) "foo"
string(3) "bar"

Example #3 Using get_class() with namespaced classes

namespace Foo\Bar;

class

Baz {
    public function 
__construct()
    {

    }
}

$baz = new \Foo\Bar\Baz;var_dump(get_class($baz));
?>

The above example will output:

See Also

  • get_called_class() - The "Late Static Binding" class name
  • get_parent_class() - Retrieves the parent class name for object or class
  • gettype() - Get the type of a variable
  • get_debug_type() - Gets the type name of a variable in a way that is suitable for debugging
  • is_subclass_of() - Checks if the object has this class as one of its parents or implements it

jjanak at webperfection dot net

8 years ago

>= 5.5

::class
fully qualified class name, instead of get_class

namespace my\library\mvc;

class

Dispatcher {}

print

Dispatcher::class; // FQN == my\library\mvc\Dispatcher$disp = new Dispatcher;

print

$disp::class; // parse error

dave at shax dot com

8 years ago

A lot of people in other comments wanting to get the classname without the namespace. Some weird suggestions of code to do that - not what I would've written! So wanted to add my own way.

function get_class_name($classname)
{
    if (
$pos = strrpos($classname, '\\')) return substr($classname, $pos + 1);
    return
$pos;
}
?>

Also did some quick benchmarking, and strrpos() was the fastest too. Micro-optimisations = macro optimisations!

39.0954 ms - preg_match()
28.6305 ms - explode() + end()
20.3314 ms - strrpos()

(For reference, here's the debug code used. c() is a benchmarking function that runs each closure run 10,000 times.)

c(
    function(
$class = 'a\b\C') {
        if (
preg_match('/\\\\([\w]+)$/', $class, $matches)) return $matches[1];
        return
$class;
    },
    function(
$class = 'a\b\C') {
       
$bits = explode('\\', $class);
        return
end($bits);
    },
    function(
$class = 'a\b\C') {
        if (
$pos = strrpos($class, '\\')) return substr($class, $pos + 1);
        return
$pos;
    }
);
?>

mail dot temc at gmail dot com

10 years ago

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 Foo {
function
doMethod(){
  echo
__METHOD__ . "\n";
}
function
doGetClassThis(){
  echo
get_class($this).'::doThat' . "\n";
}
function
doGetClass(){
  echo
get_class().'::doThat' . "\n";
}
}

class

Bar extends Foo {

}

class

Quux extends Bar {
function
doMethod(){
  echo
__METHOD__ . "\n";
}
function
doGetClassThis(){
  echo
get_class($this).'::doThat' . "\n";
}
function
doGetClass(){
  echo
get_class().'::doThat' . "\n";
}
}
$foo = new Foo();
$bar = new Bar();
$quux = new Quux();

echo

"\n--doMethod--\n"; $foo->doMethod();
$bar->doMethod();
$quux->doMethod();

echo

"\n--doGetClassThis--\n"; $foo->doGetClassThis();
$bar->doGetClassThis();
$quux->doGetClassThis();

echo

"\n--doGetClass--\n"; $foo->doGetClass();
$bar->doGetClass();
$quux->doGetClass(); ?>

OUTPUT:

--doMethod--
Foo::doMethod
Foo::doMethod
Quux::doMethod

--doGetClassThis--
Foo::doThat
Bar::doThat
Quux::doThat

--doGetClass--
Foo::doThat
Foo::doThat
Quux::doThat

ovidiu.bute [at] gmail.com

12 years ago

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:

namespace Shop;

class Foo
{
  public function
__construct()
  {
     echo
"Foo";
  }
}
//Different file include('inc/Shop.class.php'); $test = new Shop\Foo();
echo
get_class($test);//returns Shop\Foo
?>

emmanuel dot antico at gmail dot com

9 years ago

/**
* Obtains an object class name without namespaces
*/
function get_real_class($obj) {
    $classname = get_class($obj);

    if (preg_match('@\\\\([\w]+)$@', $classname, $matches)) {
        $classname = $matches[1];
    }

    return $classname;
}

macnimble at gmail dot com

10 years ago

Need a quick way to parse the name of a class when it's namespaced? Try this:

namespace Engine;
function
parse_classname ($name)
{
  return array(
   
'namespace' => array_slice(explode('\\', $name), 0, -1),
   
'classname' => join('', array_slice(explode('\\', $name), -1)),
  );
}
final class
Kernel
{
  final public function
__construct ()
  {
    echo
'

', print_r(parse_classname(__CLASS__),1), '
';
   
// Or this for a one-line method to get just the classname:
    // echo join('', array_slice(explode('\\', __CLASS__), -1));
 
}
}
new
Kernel();
?>

Outputs:
Array
(
    [namespace] => Array
        (
            [0] => Engine
        )

    [classname] => Kernel
)

Nanhe Kumar

8 years ago

class Parent{
}
class
Child extends Parent{   
}
$c = new Child();
echo
get_class($c) //Child
?>
class Parent{
  public function
getClass(){
     echo
get_class();
  }
}
class
Child extends Parent{
}
$obj = new Child();
$obj->getClass(); //outputs Parent
?>
class Parent{
  public function
getClass(){
     echo
get_class($this);
  }
}
class
Child extends Parent{
}
$obj = new Child();
$obj->getClass(); // Parent
?>

Anonymous

14 years ago

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:

public function table_name() {
        $result = null;
        if (isset($this)) { // object context
            $result = get_class($this);
        }
        else { // class context
            $result = get_class();
            $trace = debug_backtrace();
            foreach ($trace as &$frame) {
                if (!isset($frame['class'])) {
                    break;
                }
                if ($frame['class'] != $result) {
                    if (!is_subclass_of($frame['class'], $result)) {
                        break;
                    }
                    $result = $frame['class'];
                }
            }
        }
        return $result;
    }

Edward

14 years ago

The code in my previous comment was not completely correct. I think this one is.

abstract class Singleton {
    protected static $__CLASS__ = __CLASS__;

    protected function __construct() {
    }

        abstract protected function init();

        /**
     * Gets an instance of this singleton. If no instance exists, a new instance is created and returned.
     * If one does exist, then the existing instance is returned.
     */
    public static function getInstance() {
        static $instance;

                $class = self::getClass();

                if ($instance === null) {
            $instance = new $class();
            $instance->init();
        }

                return $instance;
    }

        /**
     * 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__;

        if ($implementing_class === $original_class) {
            die("You MUST provide a protected static \$__CLASS__ = __CLASS__; statement in your Singleton-class!");
        }

                return $implementing_class;
    }
}
?>

RQuadling at GMail dot com

7 years ago

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;

abstract class

Baz
{
  public function
report()
  {
    echo
     
'__CLASS__        ', __CLASS__, ' ', basename(__CLASS__), PHP_EOL,
     
'get_called_class ', get_called_class(), ' ', basename(get_called_class()), PHP_EOL;
  }
}

class

Snafu extends Baz
{
}

(new

Snafu)->report();
?>

produces output of ...

__CLASS__        Foo\Bar\Baz   Baz
get_called_class Foo\Bar\Snafu Snafu

davidsch

1 year ago

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.

e.g.

abstract class MySuperclass {
    static private
$instances = array();

    static public function

getInstance(): ACFBlock {
       
$className = get_called_class();
        if (!isset(
self::$instances[$className])) {
           
self::$instances[$className] = new static();
        }
        return
self::$instances[$className];
    }

    private function

__construct() {
       
// Singleton
    
}
}

class

MySubclass extends MySuperclass {
}
MySubclass::getInstance();

Anonymous

8 years ago

If you want the path to an file if you have i file structure like this

project -> system -> libs -> controller.php
project -> system -> modules -> foo -> foo.php

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;

class

controller {
    protected function
__construct() {
       
$this->getChildPath();
    }
    protected function
getChildPath() {
        echo
dirname(get_class($this));
    }
}
?>

$f = new foo();  // system\modules\foo
?>

Hayley Watson

5 years ago

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():

$t->Faculty();
SomeClass::Faculty(); // $t instanceof SomeClass
"SomeClass"::Faculty();
get_class($t)::Faculty();
?>

The first is legitimate, but the last makes it clear to someone reading it that Faculty() is a static method (because the name of the method certainly doesn't).

dense

5 years ago

well, if you call  get_class() on an aliased class, you will get the original class name

class Person {}class_alias('Person', 'User');$me = new User;var_dump( get_class($me) ); // 'Person'?>

var23rav at gmail dot com

8 years ago

class A
{
function __construct(){
        //parent::__construct();
        echo $this->m =  'From constructor A: '.get_class();
        echo $this->m =  'From constructor A:- argument = $this: '.get_class($this);

                echo $this->m =  'From constructor A-parent: '.get_parent_class();
        echo $this->m =  'From constructor A-parent:- argument =  $this: '.get_parent_class($this);
    }
}
class B extends A
{
function __construct(){
        parent::__construct();
        echo $this->m =  'From constructor B: '.get_class();
        echo $this->m =  'From constructor B:- argument =  $this: '.get_class($this);

                echo $this->m =  'From constructor B-parent: '.get_parent_class();
        echo $this->m =  'From constructor B-parent:- argument =  $this: '.get_parent_class($this);
    }
}
$b = new B();
//----------------output--------------------

From constructor A: A
From constructor A:- argument = $this: B
From constructor A-parent:
From constructor A-parent:- argument = $this: A
From constructor B: B
From constructor B:- argument = $this: B
From constructor B-parent: A
From constructor B-parent:- argument = $this: A

Use get_class() to get the name of class  ,it will help you get the class name, in case you extend that class with another class and want to get the name of the class to which object is instance of user get_class($object)

when you create an object of class{$b object of B} which has a super class{Class A}.
uses these code IN Super Class {A}
--------------------------------------------
to get class name B{object instance} :  get_class($this) 
to get class name A{super class}  : get_class() or get_parent_class($this)

Aaron

12 years ago

This can sometimes be used in place of get_called_class(). I used this function in a parent class to get the name of the class that extends it.

ozana at omdesign dot cz

10 years ago

Simplest way how to gets Class without namespace

namespace a\b\c\d\e\f;

class

Foo {

  public function

__toString() {
   
$class = explode('\\', __CLASS__);
    return
end($class);
  }
}

echo new

Foo(); // prints Foo
?>

Michael Richey

10 years ago

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().

abstract class Singleton {
    protected static
$m_pInstance;
    final public static function
getInstance(){
       
$class = static::getClass();
        if(!isset(static::
$m_pInstance[$class])) {
            static::
$m_pInstance[$class] = new $class;
        }
        return static::
$m_pInstance[$class];
    }
    final public static function
getClass(){
        return
get_called_class();
    }
}
// I don't remember where I found this, but this is to allow php < 5.3 to use this method.
if (!function_exists('get_called_class')) {
    function
get_called_class($bt = false, $l = 1) {
        if (!
$bt)
           
$bt = debug_backtrace();
        if (!isset(
$bt[$l]))
            throw new
Exception("Cannot find called class -> stack level too deep.");
        if (!isset(
$bt[$l]['type'])) {
            throw new
Exception('type not set');
        }
        else
            switch (
$bt[$l]['type']) {
                case
'::':
                   
$lines = file($bt[$l]['file']);
                   
$i = 0;
                   
$callerLine = '';
                    do {
                       
$i++;
                       
$callerLine = $lines[$bt[$l]['line'] - $i] . $callerLine;
                    } while (
stripos($callerLine, $bt[$l]['function']) === false);
                   
preg_match('/([a-zA-Z0-9\_]+)::' . $bt[$l]['function'] . '/', $callerLine, $matches);
                    if (!isset(
$matches[1])) {
                       
// must be an edge case.
                       
throw new Exception("Could not find caller class: originating method call is obscured.");
                    }
                    switch (
$matches[1]) {
                        case
'self':
                        case
'parent':
                            return
get_called_class($bt, $l + 1);
                        default:
                            return
$matches[1];
                    }
               
// won't get here.
               
case '->': switch ($bt[$l]['function']) {
                        case
'__get':
                           
// edge case -> get class of calling object
                           
if (!is_object($bt[$l]['object']))
                                throw new
Exception("Edge case fail. __get called on non object.");
                            return
get_class($bt[$l]['object']);
                        default: return
$bt[$l]['class'];
                    }

                default: throw new

Exception("Unknown backtrace method type");
            }
    }
}

class

B extends Singleton {
}

class

C extends Singleton {
}
$b = B::getInstance();
echo
'class: '.get_class($b);

echo

'
'
; $c = C::getInstance();
echo echo
'class: '.get_class($c);
?>
This returns:
class: b
class: c

me at nwhiting dot com

11 years ago

Method for pulling the name of a class with namespaces pre-stripped.

/**
* Returns the name of a class using get_class with the namespaces stripped.
* This will not work inside a class scope as get_class() a workaround for
* that is using get_class_name(get_class());
*
* @param  object|string  $object  Object or Class Name to retrieve name

* @return  string  Name of class with namespaces stripped
*/

function get_class_name($object = null)
{
    if (!
is_object($object) && !is_string($object)) {
        return
false;
    }
$class = explode('\\', (is_string($object) ? $object : get_class($object)));
    return
$class[count($class) - 1];
}
?>

And for everyone for Unit Test goodiness!

namespace testme\here;

class

TestClass {

        public function

test()
    {
       return
get_class_name(get_class());
    }
}

class

GetClassNameTest extends \PHPUnit_Framework_TestCase
{
    public function
testGetClassName()
    {
       
$class  = new TestClass();
       
$std  = new \stdClass();
       
$this->assertEquals('TestClass', get_class_name($class));
       
$this->assertEquals('stdClass', get_class_name($std));
       
$this->assertEquals('Test', get_class_name('Test'));
       
$this->assertFalse(get_class_name(null));
       
$this->assertFalse(get_class_name(array()));
       
$this->assertEquals('TestClass', $class->test());
    }
}
?>

dodgie74 at NOSPAM dot yahoo dot NOSPAM dot co dot uk

15 years ago

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:

class Base
{
    protected
$m_instanceName = '';

        public static function

classDisplayName()
    {
        return
'Base Class';
    }

        public function

instanceDisplayName()
    {
       
//here, we want "self" to refer to the actual class, which might be a derived class that inherits this method, not necessarily this base class
       
return $this->m_instanceName . ' - ' . self::classDisplayName();
    }
}

class

Derived extends Base
{
    public function
Derived( $name )
    {
       
$this->m_instanceName = $name;
    }

        public static function

classDisplayName()
    {
        return
'Derived Class';
    }
}
$o = new Derived('My Instance');
echo
$o->instanceDisplayName();
?>

In the above example, assuming runtime binding (where the keyword "self" refers to the actual class on which the method was invoked rather than the class in which the method is defined) would produce the output:

My Instance - 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:

My Instance - Base Class

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:

class Base
{
    protected
$m_instanceName = '';

        public static function

classDisplayName()
    {
        return
'Base Class';
    }

        public function

instanceDisplayName()
    {
       
$realClass = get_class($this);
        return
$this->m_instanceName . ' - ' . call_user_func(array($realClass, 'classDisplayName'));
    }
}

class

Derived extends Base
{
    public function
Derived( $name )
    {
       
$this->m_instanceName = $name;
    }

        public static function

classDisplayName()
    {
        return
'Derived Class';
    }
}
$o = new Derived('My Instance');
echo
$o->instanceDisplayName();
?>

Output:
My Instance - 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.

bramus at bram dot us

15 years ago

@ Frederik :

$class = $bt[count($bt) - 1]['class'];
?>

should be

$class = $bt[count($bt) - 2]['class'];
?>

;-)

yicheng zero-four at gmail dot com

15 years ago

This a response to luke at liveoakinteractive dot com and davidc at php dot net.  Static methods and variables, by definition, are bound to class types not object instances.  You should not need to dynamically find out what class a static method belongs to, since the context of your code should make it quite obvious.  Your questions reveals that you probably don't quite understand OOP quite yet (it took me a while as well).

Luke, the observed behavior from your particular code snippet makes perfect sense when you think about it.  The method getclass() is defined in BooBoof, so the __CLASS__ macro would be bound to BooBoof and defined in relation to the BooBoof class.  The fact that CooCoof is a subclass of BooBoof just means that it gains a shortcut to BooBoof::getclass().  So, in effect, you are really asking (in a convoluted way): "What is the class to which belongs the method call BooBoof::getclass()?"  The correct solution (if you actually want/need to do this) is to simply implement CooCoof::getclass() { return __CLASS__; } inside of the CooCoof definition, and any childclasses that you want to mimic this behavior.  CooCoof::getclass() will have the expected behavior.

luke at liveoakinteractive dot com

15 years ago

This note is a response to the earlier post by davidc at php dot net. Unfortunately, the solution posted for getting the class name from a static method does not work with inherited classes.

Observe the following:
class BooBoof {
  public static function
getclass() {
    return
__CLASS__;
  }

  public function

retrieve_class() {
    return
get_class($this);
  }
}

class

CooCoof extends BooBoof {
}

echo

CooCoof::getclass();
// outputs BooBoof$coocoof = new CooCoof;
echo
$coocoof->retrieve_class();
// outputs CooCoof
?>

__CLASS__ and get_class($this) do not work the same way with inherited classes. I have been thus far unable to determine a reliable way to get the actual class from a static method.

benjaminhill at gmail dot com

16 years ago

More funkyness:

class Parent {
   function displayTableName() {
      echo get_class($this);
      echo get_class();
   }
}

class Child {
   function __construct() {
      $this->displayTableName();
   }
}

Will return
- Child
- Parent

So when they say "the object isn't required in PHP5" - they don't really mean it.

refrozen dot com

17 years ago

philip at cornado dot com, it returns the value of the class from which it was called, rather than the instance's name... causing inheritance to result in unexpected returns

andregs at NOSPAM dot gmail dot NOSPAM dot com

14 years ago

After reading the previous comments, this is the best I've done to get the final class name of a subclass:

class Singleton
{
   private static
$_instances = array();
   protected final function
__construct(){}/**
    * @param string $classname
    * @return Singleton
    */
  
protected static function getInstance()
   {
     
$classname = func_get_arg(0);
      if (! isset(
self::$_instances[$classname]))
      {
        
self::$_instances[$classname] = new $classname();
      }
      return
self::$_instances[$classname];
   }

   }

class

Child extends Singleton
{
  
/**
    * @return Child
    */
  
public static function getInstance()
   {
      return
parent::getInstance(get_class());
   }
}
?>

Subclasses must override "getInstance" and cannot override "__construct".

Frederik Krautwald

15 years ago

Due to PHP 5 engine that permits to get final class in a static called function, and this is a modified version of examples published below.

abstract class Singleton {
    protected static
$_instances = array();

       protected function

__construct() {}

       protected static function

getInstance() {
       
$bt = debug_backtrace();
       
$class = $bt[count($bt) - 1]['class'];
        if (!isset(
self::$_instances[$class])) {
           
self::$_instances[$class] = new $class();
        }
        return
self::$_instances[$class];
    }
}
class
A extends Singleton {
    public static function
getInstance() {
        return
parent::getInstance();
    }
}
class
B extends Singleton {
    public static function
getInstance() {
        return
parent::getInstance();
    }
}
class
C extends A {
    public static function
getInstance() {
        return
parent::getInstance();
    }
}
$a = A::getInstance();
$b = B::getInstance();
$c = C::getInstance();

echo

"\$a is a " . get_class($a) . "
"
;
echo
"\$b is a " . get_class($b) . "
"
;
echo
"\$c is a " . get_class($c) . "
"
;
?>

I don't know about if performance would increase if debug_backtrace() is skipped and instead have getInstance() to accept a passed class retrieved by get_class() method as parameter as described in a post below.

By having set getInstance() to protected in the Singleton class, the function is required to be overridden (good OOP practice).

One thing to mention is, that there is no error checking in case $class is null or undefined, which would result in a fatal error. At the moment, though, I can't see how it could happen when the getInstance() is protected, i.e. has to be overridden in a subclass -- but with good coding practice you should always error check.

mightye at gmail dot com

15 years ago

To: Bryan

In this model it is still workable if your singleton variable is actually an array.  Consider:
abstract class Singleton {
    protected final static
$instances = array();

        protected

__construct(){}

        protected function

getInstance() {
       
$class = get_real_class(); // imaginary function returning the final class name, not the class the code executes from
       
if (!isset(self::$instances[$class])) {
           
self::$instances[$class] = new $class();
        }
        return
self::$instances[$class];
    }
}
class
A extends Singleton {
}
class
B extends Singleton {
}
$a = A::getInstance();
$b = B::getInstance();

echo

"\$a is a " . get_class($a) . "
"
;
echo
"\$b is a " . get_class($b) . "
"
;
?>
This would output:
$a is a A
$b is a B

The only alternative as described elsewhere is to make getInstance() protected abstract, accept the class name as an argument, and extend this call with a public final method for every sub-class which uses get_class() in its local object scope and passes it to the superclass.

Or else create a singleton factory like this:
final class SingletonFactory {
    protected static
$instances = array();

        protected

getInstance($class) {
        if (!isset(
self::$instances[$class])) {
           
self::$instances[$class] = new $class();
        }
        return
self::$instances[$class];
    }
}
?>
The downside to this of course to this latter model is that the class itself doesn't get to decide if it is a singleton, the calling code gets to decide this instead, and a class that really wants or *needs* to be a singleton has no way to enforce this, not even by making its constructor protected.

Basically these design patterns, and various other meta manipulations (things which operate on the nature of the object, not on the data the object holds) could benefit greatly from knowing exactly what the final type of this object is, and not having native access to this information obligates work-arounds.

janci

15 years ago

To yicheng zero-four at gmail dot com: Another, maybe better example where finding out the real class (not the class we are in) in static method should be quite usefull is the Singleton pattern.

There is currently no way how to create an abstract Singleton class that could be used just by extending it without the need to change the extended class. Consider this example:
abstract class Singleton
{
    protected static
$__instance = false;

            public static function

getInstance()
    {   
        if (
self::$__instance == false)
        {
           
// This acctually is not what we want, $class will always be 'Singleton' :(
           
$class = get_class();
           
self::$__instance = new $class();           
        }
        return
self::$__instance;
    }
}

class

Foo extends Singleton
{
   
// ...
}$single_foo = Foo::getInstance();
?>
This piece of code will result in a fatal error saying: Cannot instantiate abstract class Singleton in ... on line 11

The best way I figured out how to avoid this requires simple but still a change of the extended (Foo) class:
abstract class Singleton
{
    protected static
$__instance = false;

            protected static function

getInstance($class)
    {   
        if (
self::$__instance == false)
        {
            if (
class_exists($class))
            {
               
self::$__instance = new $class();           
            }
            else
            {
                throw new
Exception('Cannot instantiate undefined class [' . $class . ']', 1);
            }
        }
        return
self::$__instance;
    }
}

class

Foo extends Singleton
{
   
// You have to overload the getInstance method in each extended class:
   
public static function getInstance()
    {
        return
parent::getInstance(get_class());
    }
}
$single_foo = Foo::getInstance();
?>

This is of course nothing horrible, you will propably need to change something in the extended class anyway (at least the constructor access), but still... it is just not as nice as it possibly could be ;)

MagicalTux at FF.ST

18 years ago

Note that the constant __CLASS__ is different from get_class($this) :
  class test {
    function whoami() {
      echo "Hello, I'm whoami 1 !\r\n";
      echo "Value of __CLASS__ : ".__CLASS__."\r\n";
      echo "Value of get_class() : ".get_class($this)."\r\n\r\n";
    }
  }
  class test2 extends test {
    function whoami2() {
      echo "Hello, I'm whoami 2 !\r\n";
      echo "Value of __CLASS__ : ".__CLASS__."\r\n";
      echo "Value of get_class() : ".get_class($this)."\r\n\r\n";
      parent::whoami(); // call parent whoami() function
    }
  }
  $test=new test;
  $test->whoami();
  $test2=new test2;
  $test2->whoami();
  $test2->whoami2();
?>

The output is :
Hello, I'm whoami 1 !
Value of __CLASS__ : test
Value of get_class() : test

Hello, I'm whoami 1 !
Value of __CLASS__ : test
Value of get_class() : test2

Hello, I'm whoami 2 !
Value of __CLASS__ : test2
Value of get_class() : test2

Hello, I'm whoami 1 !
Value of __CLASS__ : test
Value of get_class() : test2

In fact, __CLASS__ returns the name of the class the function is in and get_class($this) returns the name of the class which was created.

dave dot zap at gmail dot com

14 years ago

Take care using the backtrace method to find the calling class of a static method, you should step backward through the array and find a match for your getInstance() function. In backtrace the class name you want is not always the last item in the array.

I will not post the whole singleton class here, but have made the following modification to Frederik Krautwald's method (found below)

$bt = debug_backtrace();
// this method is count($bt)-1) by Frederik will fall over when calling getInstance from within an include file.
//$class = $bt[count($bt) - 1]['class'];
for( $i=count($bt)-1 ; $i > 0 ; $i--)
{
    if(
$bt[$i]['function'] == 'getInstance')
    {
       
$class = $bt[$i]['class'];
        break;
    }
}
?>

XyQrTw

5 years ago

To get class name without the Namespace you can use easily this trick :
namespace My\Long\Namespace;

class

MyClass {

    static function

getClassName() {
        return
basename(__CLASS__);
      
// or with get_class();
       
return basename(get_class());
    }

}

echo \

My\Long\Namespace\MyClass::getClassName(); // Display : MyClass
?>

danbettles at yahoo dot co dot uk

13 years ago

It is possible to write a completely self-contained Singleton base class in PHP 5.3 using the new get_called_class function.  When called in a static method, this function returns the name of the class the call was made against.

abstract class Singleton {

    protected function

__construct() {
    }

    final public static function

getInstance() {
        static
$aoInstance = array();$calledClassName = get_called_class();

        if (! isset (

$aoInstance[$calledClassName])) {
           
$aoInstance[$calledClassName] = new $calledClassName();
        }

        return

$aoInstance[$calledClassName];
    }

    final private function

__clone() {
    }
}

class

DatabaseConnection extends Singleton {

    protected

$connection;

    protected function

__construct() {
       
// @todo Connect to the database
   
}

    public function

__destruct() {
       
// @todo Drop the connection to the database
   
}
}
$oDbConn = new DatabaseConnection();  // Fatal error$oDbConn = DatabaseConnection::getInstance();  // Returns single instance
?>

Full write-up in Oct 2008: http://danbettles.blogspot.com

Edward

14 years ago

With Late Static Bindings, available as of PHP 5.3.0, it is now possible to implement an abstract Singleton class with minimal overhead in the child classes. Late static bindings are explained here: http://nl2.php.net/manual/en/language.oop5.late-static-bindings.php

In short, it introduces a new 'static::' keyword, that is evaluated at runtime. In the following code I use it to determine the classname of the child Singleton class.

abstract class Singleton {
    protected static $__CLASS__ = __CLASS__;
    protected static $instance;

        protected function __construct() {
        static::$instance = $this;
        $this->init();
    }

        abstract protected function init();

        protected function getInstance() {
        $class = static::getClass();

                if (static::$instance===null) {
            static::$instance = new $class;
        }

        return static::$instance;
    }

        private static function getClass() {
        if (static::$__CLASS__ == __CLASS__) {
            die("You MUST provide a protected static \$__CLASS__ = __CLASS__; statement in your Singleton-class!");
        }

                return static::$__CLASS__;
    }
}
?>

An example Singleton class can then be implemented as follows:

class A extends Singleton {
    protected static $__CLASS__ = __CLASS__; // Provide this in each singleton class.

    protected function someFunction() {
        $instance = static::getInstance();
        // ...
    }
}
?>

Hope this helps you save some time :)

Lanselot

13 years ago

Beware if you're omitting the parameter on inherited classes.
It'll return the class name of the method where it's called.

class A {
    function
foo() {
      return
get_class();
    }
}
class
B extends A {
   function
bar() {
      return
get_class();
   }
}
$instance = new B();
echo
$instance->bar(); //Prints 'B';
echo $instance->foo(); //Prints 'A';
?>

kiril (AT) aternus networks

4 years ago

If you want the Class Name without the Namespace or if you've got here because basename() returns a dot (.) for the FQCN (Fully Qualified Class Name), here is the solution:

// FQCN: App\Http\Controllers\CustomerReportControllersubstr(self::class, (int)strrpos(self::class, '\\') + 1)// returns: CustomerReportController
?>

How do you print an object of an object in PHP?

The print_r() function is a built-in function in PHP and is used to print or display information stored in a variable. Parameters: This function accepts two parameters as shown in above syntax and described below. $variable: This parameter specifies the variable to be printed and is a mandatory parameter.

What is object in PHP with example?

An Object is an individual instance of the data structure defined by a class. We define a class once and then make many objects that belong to it. Objects are also known as instances.

What is a stdClass object?

The stdClass is the empty class in PHP which is used to cast other types to object. It is similar to Java or Python object. The stdClass is not the base class of the objects. If an object is converted to object, it is not modified.

How do you access the properties of an object in PHP?

Within class methods non-static properties may be accessed by using -> (Object Operator): $this->property (where property is the name of the property). Static properties are accessed by using the :: (Double Colon): self::$property .