2014-12-02 46 views
-1

单例类:PHP Singleton类 - 致命错误:调用私有的MyObject :: __结构()

<?php 

class db_singleton 
{ 
    const ORACLE_HOST = "SOMEIP"; 
    const ORACLE_USER = "validuser"; 
    const ORACLE_PASS = "validpass"; 
    const ORACLE_DB = "SOMEIP/DBNAME"; 

    private static $instance; // stores the oci_* instance 

    private function __construct() { } // block directly instantiating 

    private function __clone() { } // block cloning of the object 


    public static function call() 
    { 

     // create the instance if it does not exist 
     if(!isset(self::$instance)) 
     { 
      // the ORACLE_* constants should be set to or 
      // replaced with your db connection details 
      self::$instance = oci_connect(self::ORACLE_USER, self::ORACLE_PASS, self::ORACLE_DB); 
      if(self::$instance->connect_error) 
      { 
       throw new Exception('Oracle connection failed: ' . self::$instance->connect_error); 
      } 
     } 
     // return the instance 
     return self::$instance; 
    } 


     public function __destruct() { 
     oci_close($instance); 
    } 

    public function queryresult($query) 
    { 

      $result_set_array =array(); 
      $this->stmt = oci_parse($this->con, $query); 
      oci_execute($this->stmt); 

      while($row=oci_fetch_array($this->stmt,OCI_ASSOC+OCI_RETURN_NULLS)) 
      { 

       $result_set_array[] = $row; 
      } 
      oci_free_statement($this->stmt); 
      return $result_set_array; 

    } 
} 
?> 

当我尝试使用singleton类下面的代码,它可以完美运行,并获取结果。

$conn = db_singleton::call(); 
$stid = oci_parse($conn, 'SELECT * FROM somevalid_table'); 
oci_execute($stid); 
while($result=oci_fetch_array($stid,OCI_ASSOC+OCI_RETURN_NULLS)) 
    { 
    $result_set_array[] = $result; 
} 

现在,当我尝试使用模型扩展我的课,它会抛出异常

class Myclass Extends db_singleton{ 

public function someModel() 
    { 

     $result = parent::queryresult(" select * from somevalid_table"); 
     return $result; 
    } 
} 

例外:

Fatal error: Call to private db_singleton::__construct() from context 'someController' 

我知道,类不能有私有构造函数实例化。 __construct()函数总是在实例化对象时调用,所以试图执行类似$ x = new MyObject()将导致私有构造函数的致命错误。

我正在使用Singleton类来防止直接实例化一个对象。我该如何克服问题?什么是最好的解决方案?

谢谢。

+1

向你的子类添加一个空构造函数。这将覆盖私有的父类构造函数。 – 2014-12-02 07:37:57

+0

它会影响单身模式吗? – Slimshadddyyy 2014-12-02 07:41:13

+0

如果你想真正的单身人士行为不扩展单身人士类。 – 2014-12-02 07:48:55

回答

0

PHP类脚本:

class db_singleton 
{ 
    const ORACLE_USER = "validuser"; 
    const ORACLE_PASS = "validpass"; 
    const ORACLE_DB = "SOMEIP/DBNAME"; 

    private static $instance = null; // stores the oci_* instance 

     // private constructor 
     private function __construct() { } // block directly instantiating 

    private function __clone() { trigger_error('Clone is not allowed.', E_USER_ERROR); } // block cloning of the object 

    public static function getInstance() 
    { 

     // create the instance if it does not exist 
     if(!isset(self::$instance)) 
     { 
      // the ORACLE_* constants should be set to or 
      // replaced with your db connection details 
         self::$instance = oci_connect(self::ORACLE_USER, self::ORACLE_PASS, self::ORACLE_DB); 
      if(self::$instance->connect_error) 
      { 
       throw new Exception('Oracle connection failed: ' . self::$instance->connect_error); 
      } 
     } 
     // return the instance 
     return self::$instance; 
    } 

    public static function queryresult($query) 
    { 

      $result_set_array =array(); 
      $stmt = oci_parse(db_singleton::getInstance(), $query); 
      oci_execute($stmt); 

      while($row=oci_fetch_array($stmt,OCI_ASSOC+OCI_RETURN_NULLS)) 
      { 
          $result_set_array[] = $row; 
      } 
      oci_free_statement($stmt); 
      return $result_set_array; 

} 

我们防止Fatal error: Call to private db_singleton::__construct(),我有在我的情况下,我的child class增加了empty constructor这是model类。这将覆盖私有的父类构造函数。

class Myclass Extends db_singleton{ 

    public function __construct() {} 

    public function someModel(){ 

      $result = parent::queryresult(" select * from somevalid_table"); 
      return $result; 
    } 
} 

希望它有助于某人。

谢谢。

0

$x = new MyObject()如果您的构造函数在该类中是私有的,将永远不会工作,因为__construct()是在创建对象时调用的第一个方法。

Create a public method 
/** 
* Singleton class 
* 
*/ 
final class UserFactory 
{ 
    /** 
    * Call this method to get singleton 
    * 
    * @return UserFactory 
    */ 
    public static function Instance() 
    { 
     static $inst = null; 
     if ($inst === null) { 
      $inst = new UserFactory(); 
     } 
     return $inst; 
    } 

    /** 
    * Private ctor so nobody else can instance it 
    * 
    */ 
    private function __construct() 
    { 

    } 
} 

要使用:

$fact = UserFactory::Instance(); 
$fact2 = UserFactory::Instance(); 

$fact == $fact2; 

但是:

$fact = new UserFactory() 
+0

是的,那么建议的解决方案是什么? – Slimshadddyyy 2014-12-02 07:32:04

+0

您必须创建一个静态方法来重新创建实例 – 2014-12-02 07:32:59

+0

'$ x = db_singleton :: Instance();'这适用于我,正如我所说的那样。但是当我尝试在模型中扩展类时,它不会。 – Slimshadddyyy 2014-12-02 07:35:34