如何在扩展类中访问单例类对象

Plz tell me where i'm doing wrong...

I've 3 classes. These are like this..

  1. Singleton class where i'm following singleton design pattern
  2. Class ram
  3. Class sam

In 'ram' class i'm setting data for singleton class object.

Now, in 'sam' class.. i'm trying to access singleton class object inside show_data() function of sam class.

When, i'm using..

Print_r($this) : showing empty object

but, when i'm using following code..

$singleton_obj = Singleton::getInstance();
print_r($singleton_obj); : Showing content of singleton object

My question is, why in-case of Print_r($this) it's showing empty object. Is there any way, i can get content of singleton class object by using Print_r($this).

MY class file is this..

<?php 
class Singleton
{
 // A static property to hold the single instance of the class
private static $instance;

// The constructor is private so that outside code cannot instantiate
public function __construct() { }

// All code that needs to get and instance of the class should call
// this function like so: $db = Database::getInstance();
public function getInstance()
{
  // If there is no instance, create one
  if (!isset(self::$instance)) {
    $c = __CLASS__;
    self::$instance = new $c;
  }
  return self::$instance;
}

// Block the clone method
private function __clone() {}


// Function for inserting data to object
public function insertData($param, $element)
{
$this->{$param} = $element;
}
}

//---CLASS ram---
class ram
{
    function __construct() 
    {
        $db = Singleton::getInstance();
        $db->insertData('name', 'Suresh');
    }
}

$obj_ram = new ram;

//---CLASS sam---
class sam extends Singleton
{
    function __construct()
    {
        parent::__construct();
   }

   public function show_data()
   {
    echo "<br>Data in current object<br>";
    print_r($this);

    echo "<br><br>Data in singleton object<br>";
        $singleton_obj = Singleton::getInstance();
        print_r($singleton_obj);
   } 
}

$obj_sam = new sam;
echo $obj_sam->show_data(); 
?>

You are creating a "sam" object by "new sam", you sould use "sam::getInstance()"; to reach the static instance but it won't be "sam object" type will be "Singleton" "."__CLASS__" gives the scope class not the real object class.

First: you must read about "late static binding" in php and learn the limitations of self:: and __CLASS__ use "static::" instead of "self::" (5.3+)

Or you can change all the pattern use statics like;

   <?php 
    class Singleton
    {
        // A static property to hold the single instance of the class
        private static $instance;

        // The constructor is private so that outside code cannot instantiate
        public function __construct() { }

        // All code that needs to get and instance of the class should call
        // this function like so: $db = Database::getInstance();
        public static function getInstance()
        {
            // If there is no instance, create one
            if (!isset(self::$instance)) {
                $c = __CLASS__;
                self::$instance = new $c;
            }
            return self::$instance;
        }

        // Block the clone method
        private function __clone() {}


        // Function for inserting data to object
        public function insertData($param, $element)
        {
            $this->{$param} = $element;
        }
    }

    //---CLASS ram---
    class ram
    {
        function __construct() 
        {
            $db = Singleton::getInstance();
            $db->insertData('name', 'Suresh');
        }
    }

    $obj_ram = new ram;

    //---CLASS sam---
    class sam extends Singleton
    {
        function __construct()
        {
            parent::__construct();
        }

        public static function show_data()
        {
            echo "<br>Data in current object<br>";
            print_r(self::getInstance());
            echo "<br><br>Data in singleton object<br>";
            $singleton_obj = Singleton::getInstance();
            print_r($singleton_obj);
        } 
    }

$obj_sam = sam::getInstance();
print_r($obj_sam);

    echo sam::show_data();

This is an example which setting the properties pointers to the current object like "CI"

<?php 
    class Singleton
    {
        // A static property to hold the single instance of the class
        private static $instance;

        // The constructor is private so that outside code cannot instantiate
        public function __construct() {

            if(isset(self::$instance))
                foreach(self::$instance as $key => &$val)
                {
                    $this->{$key} = &$val;
            }
        }



        // All code that needs to get and instance of the class should call
        // this function like so: $db = Database::getInstance();
        public static function getInstance()
        {
            // If there is no instance, create one
            if (!isset(self::$instance)) {
                $c = __CLASS__;
                self::$instance = new $c;
            }
            return self::$instance;
        }

        // Block the clone method
        private function __clone() {}


        // Function for inserting data to object
        public function insertData($param, $element)
        {
            $this->{$param} = $element;
        }
    }

    //---CLASS ram---
    class ram
    {
        function __construct() 
        {
            $db = Singleton::getInstance();
            $db->insertData('name', 'Suresh');
        }
    }

     class ram2
    {
        function __construct() 
        {
            $db = Singleton::getInstance();
            $db->insertData('name', 'Suresh');
            $db->insertData('name2', 'Suresh2');
        }
    }

    $obj_ram = new ram;
    $obj_ram = new ram2;

    //---CLASS sam---
    class sam extends Singleton
    {
        function __construct()
        {
            parent::__construct();
        }

        public function show_data()
        {
            echo "<br>Data in current object<br>";
            print_r($this);

            echo "<br><br>Data in singleton object<br>";
            $singleton_obj = Singleton::getInstance();
            print_r($singleton_obj);
        } 
    }

    $obj_sam = new sam;
    echo $obj_sam->show_data(); 

Your singleton is not getting 'initialized' - it does not create any object. So $this is referring to nothing.

EDIT: Turns out I'm wrong - I've usually seen Singletons declare __construct() as private. That's how new instances of the class are denied from being instantiated. Not sure what's going on in your case though.

EDIT 2: What is the problem? Your code behaves as expected. You're creating a new sam with no data in it, so you are getting an empty object. And when you print the singleton object, you are seeing the Singleton's data.

EDIT 3: I've never seen Singletons being extended. I think that's the wrong application of the pattern, I might be wrong of course.

You can't access static properties of class from within that class object.

A property declared as static can not be accessed with an instantiated class object (though a static method can).

http://php.net/manual/en/language.oop5.static.php