【问题标题】:How to access singleton class object in extended class如何访问扩展类中的单例类对象
【发布时间】:2012-07-08 09:57:48
【问题描述】:

请告诉我哪里做错了...

我有 3 节课。这些是这样的..

  1. 我遵循单例设计模式的单例类
  2. 类内存
  3. 类山姆

在“ram”类中,我正在为单例类对象设置数据。

现在,在“sam”类中。我正在尝试访问 sam 类的 show_data() 函数中的单例类对象。

什么时候,我正在使用..

Print_r($this) : showing empty object

但是,当我使用以下代码时..

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

我的问题是, 为什么在 Print_r($this) 的情况下它显示的是空对象。有什么办法,我可以使用 Print_r($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(); 
?>

【问题讨论】:

  • 如果您的 insertData 函数有一个额外的 },至少在此处的代码中不确定这只是一个错字还是您的代码中是否存在。
  • 为什么 getInstance 不是静态方法?
  • 您的评论说 __construct() 是 private 但您的代码声明它是公开的?
  • @Laxus 它需要是静态的吗?我对 PHP 的 OOP 知识并不深入。顺便说一句,即使我将其更改为静态,它也不会产生任何效果。
  • 您的代码按预期运行。你不应该尝试扩展单例。这不是使用模式的方式。您只需要一个 Singleton 实例 - 没有克隆或子项。

标签: php object singleton this


【解决方案1】:

您正在通过“new sam”创建一个“sam”对象,您应该使用“sam::getInstance()”;到达静态实例但它不会是“sam object”类型将是“Singleton”“。”__CLASS__”给出范围类而不是真实对象类。

首先:你必须阅读php中的“late static binding”,了解self::和__CLASS__使用的局限性“static::”而不是“self::”(5.3+)

或者你可以改变所有的模式使用静态像;

   <?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();

这是一个将属性指针设置为当前对象的示例,例如“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(); 

【讨论】:

  • 嘿,非常感谢您通过显示准确的代码来帮助我。这真的很有帮助。你能告诉我,'sam' 类的 show_data() 中是否有任何机制。我可以使用 $this 获取单例对象的所有数据。 Ex : print_r($this) : // 应该给出所有单例对象数据
  • 如果你想使用 "$this" 你必须把你的代码写到 Singleton 类,因为 "$instance" 的类型是 "Singleton"。如果您想要 Singleton 对象属性,为什么不使用“Singleton::getInstnace()”?
  • 嘿,我不太擅长 PHP OOP。你能通过显示一些代码来帮助我吗?我的意思是,我需要在单例类中写什么。这样,在“sam”类的 show_data() 中,我可以通过 $this 获取这些数据。
  • 嘿,我想你对 codeigniter 很熟悉。我只想要像 CI 一样的方式。从任何控制器类使用 $this 我需要访问单例对象的所有数据。
  • 阅读 Core-Controller.php 的代码 github.com/EllisLab/CodeIgniter/blob/develop/system/core/… 它正在获取静态实例并在构造函数方法之后重建对象(该死!),现在,我将重写你的代码等待。
【解决方案2】:

你的单例没有被“初始化”——它没有创建任何对象。所以$this 什么都没有。

编辑:原来我错了——我经常看到单身人士将 __construct() 声明为private。这就是拒绝实例化类的新实例的方式。不知道你的情况是怎么回事。

编辑 2:有什么问题?您的代码按预期运行。您正在创建一个新的sam,其中没有数据,因此您得到一个空对象。当您打印单例对象时,您会看到单例的数据。

编辑 3:我从未见过单例被扩展。我认为这是模式的错误应用,我当然可能是错的。

【讨论】:

  • @adiya menon 通过这段代码,我正在初始化单例.. //---CLASS ram--- class ram { function __construct() { $db = Singleton::getInstance(); $db->insertData('name', 'Suresh'); } } $obj_ram = 新内存;
  • 嘿,我想要 $this 指针中的单例类对象。因此,每当我使用 Print_r($this).. 时,我都可以获得单例对象的所有数据。
  • 朋友,这件事你需要仔细阅读,这是错误的做法。
  • 嘿,你见过 PHP 的 codeigniter 框架吗?他们使用相同的技术。他们有一个主要的单例控制器类,并且在其他控制器类中扩展了该类。我只是想模仿这种技术,但.. 不知道我在哪里做错了。
  • 是的,刚刚去看了 CI 的代码,我也不明白那里发生了什么,看起来像一个问题,我要从中学习一些东西 :) 祝你好运!
【解决方案3】:

您不能从该类对象中访问该类的静态属性。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 2014-05-04
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多