PHP Singleton Class - 致命错误:调用私有 MyObject::__construct()


PHP Singleton Class - Fatal error: Call to private MyObject::__construct()

Singleton Class:

<?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类来防止对象的直接实例化。我怎样才能克服问题?最好的解决方案是什么?

谢谢。

如果您的构造函数在该类中是私有的,则$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()

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;
    }   
}

希望它对某人有所帮助。

谢谢。