Using the singleton method to create a global object - php

I am trying to use the singleton method to access a global object (in this example its "username"). My question is how can I modify this so that in the DB->connect() function I could do echo $this->username; without declaring $username or changing the last 2 lines?
class CI_Base {
private static $instance;
public function CI_Base()
{
self::$instance =& $this;
}
public static function &get_instance()
{
return self::$instance;
}
}
function &get_instance() {
return CI_Base::get_instance();
}
class Foo {
function run() {
$CI = & get_instance();
$CI->username = "test";
$db = new DB;
$db->connect();
}
}
class DB extends Foo {
function connect() {
$CI = & get_instance();
echo $CI->username;
}
}
$foo = new Foo;
$foo->run();

This should work
class Foo {
function __get($field) {
if ($field == "username") {
//don't need to create get_instance function
$CI = CI_Base::get_instance();
return $CI->username;
}
}
}
you can pass all access to non existing fields from Foo to $instance object:
class Foo {
function __get($field) {
$CI = CI_Base::get_instance();
return $CI->$field;
}
}
class DB extends Foo {
function connect() {
// this->username will call __get magic function from base class
echo this->username;
}
}
in php5 you don't need to put ampersand before get_instance becouse all objects are passed by reference.

Related

Echo variable which has been set in another classes function

I am trying to access the contents of a variable from another class. I have the code below, I am expecting to get 'test' returned, I get nothing.
I assume this is because it is getting $abc_rank as empty. It is required that the variable is populated in the function itself.
Therefore how can I get $abc_rank to hold that echo and output via the other class?
<?php
class class1 {
public static $abc_rank;
public function __construct() {
$this->add_text();
}
public function add_text() {
$this->abc_rank = 'test';
}
}
class class2 {
public function __construct() {
$this->display();
}
public function display() {
$test = class1::$abc_rank;
echo $test;
}
}
$go = new class2();
?>
I know I can do:
public static $abc_rank = 'test';
But the population of the variable must be in a function.
I have read some of the other related answers and can't seem to get this to work.
In class1 :
Replace $this->abc_rank = 'test'; with $this::$abc_rank='test';
($abc_rank is a static property)
In class2 :
In your display function : replace
$test = class1::$abc_rank;
echo $test;
with
$test = new class1();
echo $test::$abc_rank;
(class1 isn't static)
Full code here :
class class1 {
public static $abc_rank;
public function __construct() {
$this->add_text();
}
public function add_text() {
//$this->abc_rank = 'test';
$this::$abc_rank='test';
}
}
class class2 {
public function __construct() {
$this->display();
}
public function display() {
//$test = class1::$abc_rank;
//echo $test;
$test = new class1();
echo $test::$abc_rank;
}
}
$go = new class2();
you have to create the class1 to run the constructor of this class.
class class1 {
public static $abc_rank;
public function __construct() {
$this->add_text();
}
public function add_text() {
self::$abc_rank = 'test';
}
}
class class2 {
public function __construct() {
$this->display();
}
public function display() {
$test = class1::$abc_rank;
echo $test;
}
}
new class1();
$go = new class2();

PHP Use child variable to create a class in parent class

I have 3 classes:
Class A - Parent Class
Class B - Child Class
Class C - Class to be used in Class A
I want to use functions from class C using variables from my Child class.
<?php
class A
{
public function __construct()
{
$this->load();
}
public function load()
{
$class = new C();
$class->test = $this->test;
$this->c = $class;
}
}
class B extends A
{
public function __construct()
{
parent::__construct();
}
}
class C
{
public function display()
{
echo $this->test;
}
}
$b = new B();
$b->test = 1;
$b->c->display();
Your problem is here:
$class->test = $this->test;
You are attempting to use a property that is not yet defined, because when you do this:
$b->test = 1;
the constructor has already been called, and there's nothing in your classes to update C with the value of B's test property.
You can solve this in a couple of different ways.
1) Send the value in B's constructor, and pass it down the entire chain:
class A
{
public function __construct($test)
{
$this->load($test);
}
public function load($test)
{
$class = new C();
$class->test = $test;
$this->c = $class;
}
}
class B extends A
{
public function __construct($test)
{
parent::__construct($test);
}
}
class C
{
public function display()
{
echo $this->test;
}
}
$b = new B(123);
$b->c->display();
2) Add a method to B that will update C's property:
<?php
class A
{
public function __construct()
{
$this->load();
}
public function load()
{
$class = new C();
$this->c = $class;
}
}
class B extends A
{
public function __construct()
{
parent::__construct();
}
public function setTest($test)
{
$this->c->test = $test;
}
}
class C
{
public function display()
{
echo $this->test;
}
}
$b = new B();
$b->setTest(123);
$b->c->display();
Or perhaps a combination of both.

Accessing an object declared in parent class in PHP

Edit: Original example removed as it was complex.
The codes provided below doesn't work. I am trying to access the methods defined in a class which is declared in the parent class.
Here is a sample code. Its not working and I'd like to know why
<?php
function & get_instance()
{
return Main::get_instance();
}
class Db{
function select($var)
{
echo $var;
}
}
class Main
{
public $db ;
public $process ;
private static $instance;
function __construct()
{
self::$instance = &$this;
$this->db = new Db ;
$this->process = Process;
}
public static function & get_instance()
{
return self::$instance;
}
}
class Process{
private $main ;
function __construct()
{
$this->main = get_instance() ;
}
function processPayment()
{
$this->main->db->select("hello");
}
}
$main = new Main ;
$main->process->processPayment();
To access members of a parent class, you will have to declare those members protected or public.
For example:
public var $db;
protected var $orders;

Can you instantiate an object inside another class?

Is it possible to declare an object inside another class? The following code keeps giving me an error nexpected 'new' (T_NEW) error.
Class class1{
public function doSomething(){
$var = 3;
return true;
}
}
Class class2{
public $class1 = new class1();
public function doSomethingElse(){
if($class1->doSomething() == true){
return 10;
}else{
return 13;
}
}
}
//$obj = new class2();
I don't really want want to pass in the object through a constructor, because it's used inside other classes, so I'd have to pass it through multiple times. Is there a better method?
Use the Constructor of your class to instantiate the other class.
Class class1
{
public function doSomething()
{
$var = 3;
return true;
}
}
Class class2
{
protected $class1 = null;
public function __construct()
{
$this->class1 = new class1();
}
public function doSomethingElse()
{
if ($this->class1->doSomething() == true) {
return 10;
} else {
return 13;
}
}
}
Yes, but you have to put the initialization in construction method.
Class class2{
public $class1;
  public function __construct() {
$this->class1 = new class1();
}
// ...
}
You can only initialize scalar values and arrays, use the constructor:
class Class2 {
public $class1;
public function __construct() {
$this->class1 = new Class1();
}
...
}

What's wrong in this singleton class

I've 3 classes. [1]Singleton [2]Load [3]Dashboard . In Load class there is one method called 'model()'. Where i'm initializing data for singleton object by using this code.
$obj = Singleton::getInstance();
$obj->insertData('email', 'mail#domain.com');
Again, from Dashboard class there is one method called 'show()' from where i'm trying to print the Singleton object data. But, here i can see all the data of Singleton object except the data which has been initialized by 'model' method of 'Load' class.
Here is my full code...
<?php
//---Singletone Class---
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;
}
}
//---LOAD class---
class Load
{
function __construct()
{
$obj = Singleton::getInstance();
$obj->insertData('country', 'INDIA');
}
function model()
{
$this->name = 'Suresh';
$obj = Singleton::getInstance();
$obj->insertData('email', 'mail#domain.com');
}
function msg()
{
return('<br><br>This message is from LOAD class');
}
}
$obj = Singleton::getInstance();
$load = new load();
$obj->load = $load;
//---Dashboard Class---
class Dashboard extends Singleton
{
function __construct()
{
parent::__construct();
}
function show()
{
echo "Default data in current Object";
echo "<br>";
print_r($this);
echo $this->load->msg();
$this->load->model();
echo "<br><br>Data in current Object after post intialization";
echo "<br>";
print_r($this);
}
}
$dashboard = new dashboard();
$dashboard->show();
If your singleton was truly a singleton then the update would have worked. I'm suspecting that you may have multiple instances of the singleton class that is initialized.
Edit:
Also its not a good idea to inherit from a true singleton class.
You need to remove the inheritance that Dashboard has on Singleton
Edit:
Best practice on PHP singleton classes
I don't like your direct access to an object like an array. This one is a better approach [see here]:
You should call it like this:
$obj = Singleton::getInstance();
$load = new Load();
$obj->insertData( 'load', $load );
Implementation of Singleton:
class Singleton
{
// A static property to hold the single instance of the class
private static $instance;
// my local data
protected $_properties;
// You might want to move setter/getter to the end of the class file
public function __set( $name, $value )
{
$this->_properties[ $name ] = $value;
}
public function __get( $name )
{
if ( ! isset( $this->_properties[ $name ] )) {
return null;
}
return $this->_properties[ $name ];
}
// No need to check, if single instance exists!
// __construct can only be called, if an instance of Singleton actually exists
private function __construct() {
$this->_properties = array();
foreach(self::$instance as $key => &$val)
{
$this->_properties{$key} = &$val;
}
}
public static function getInstance()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}
// Function for inserting data to object
public function insertData($param, $element)
{
$this->_properties{$param} = $element;
}
// Block the clone method
private function __clone() {}
}

Categories