PHP Singleton类 - 致命错误:调用私有MyObject :: __ construct()

时间:2014-12-02 07:26:19

标签: php class model singleton

Singleton类:

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

感谢。

2 个答案:

答案 0 :(得分: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()

答案 1 :(得分: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(),我已经empty constructor添加了child class我的modelclass Myclass Extends db_singleton{ public function __construct() {} public function someModel(){ $result = parent::queryresult(" select * from somevalid_table"); return $result; } } 。这将覆盖私有的父类构造函数。

{{1}}

希望它有所帮助。

感谢。