Plz tell me where i'm doing wrong...
I've 3 classes. These are like this..
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).