1

我在 mysql-connect 页面上的 php.net 上找到了一个 db 适配器。
这是一个浏览量很大的页面(我想)。

它包括作者声称的单例模式类。

在http://php.net/manual/en/function.mysql-connect.php上找到

作家说:

“这是一个管理单个数据库连接的单例类。Open 方法使用常量值作为默认值,通过在每个网页顶部加载的初始化程序脚本从 ini 文件中读取。您还可以通过手动输入来覆盖默认值自己的(如果您需要在脚本中切换服务器或数据库名称)。qry 函数采用准备好的语句,并将根据第二个参数返回第一行、第一个关联行、第一个单元格或整个结果集(整个结果如果省略)。”

用法:$DB = DB::Open();
$result = $DB->qry(" {SQL 语句} ;");

<?php
    abstract class Database_Object
    {
        protected static $DB_Name;
        protected static $DB_Open;
        protected static $DB_Conn;

        protected function __construct($database, $hostname, $hostport, $username, $password)
        {
            self::$DB_Name = $database;
            self::$DB_Conn = mysql_connect($hostname . ":" . $hostport, $username, $password);
            if (!self::$DB_Conn) { die('Critical Stop Error: Database Error<br />' . mysql_error()); }
            mysql_select_db(self::$DB_Name, self::$DB_Conn);
        }

        private function __clone() {}

        public function __destruct()
        {
//            mysql_close(self::$DB_Conn);  <-- commented out due to current shared-link close 'feature'.  If left in, causes a warning that this is not a valid link resource.
        }
    }

    final class DB extends Database_Object
    {
        public static function Open($database = DB_NAME, $hostname = DB_HOST, $hostport = DB_PORT, $username = DB_USER,$password = DB_PASS)
        {
            if (!self::$DB_Open)
            {
                self::$DB_Open = new self($database, $hostname, $hostport, $username, $password);
            }
            else
            {
                self::$DB_Open = null;
                self::$DB_Open = new self($database, $hostname, $hostport, $username, $password);
            }
            return self::$DB_Open;
        }

        public function qry($sql, $return_format = 0)
        {
            $query = mysql_query($sql, self::$DB_Conn) OR die(mysql_error());
            switch ($return_format)
            {
                case 1:
                    $query = mysql_fetch_row($query);
                    return $query;
                    break;
                case 2:
                    $query = mysql_fetch_array($query);
                    return $query;
                    break;
                case 3:
                    $query = mysql_fetch_row($query);
                    $query = $query[0];
                    return $query;
                default:
                    return $query;
            }
        }
    }
?>

看了代码我有一个疑问,这真的是单例吗(见 DB 类和 Open 函数)?

静态属性如何使单例模式起作用?

4

1 回答 1

1

我明白你的意思,如果self::$DB_Open确实存在,它将它设置为 null 并创建对象的新实例。

看来你是对的,这似乎不像单例模式。

关于具有静态属性的单例模式。与对象范围内的实例变量不同,静态变量在类范围内
这意味着即使您多次创建一个对象,它每次仍将使用相同的静态属性值。这就是让它们非常适合计数器和全局单例的原因。

见下文:

Class A {
static int y=1;
int x=3;
}
$newA = new A();
$newB = new A();
$newC = new A();

以上创建了 x 的 3 个实例。您可以在 1 个实例中进行更改,它只会在该 1 个实例中进行更改。
但是只创建了 1 个 y 实例。所以 1 的变化和所有 3 的变化都会改变。它们都存在于相同的上下文中。因此指向相同的值。如果您增加一个,其他人将显示相同的增量等。

所以要重新迭代,即使只存在一个实例,DB_Conn它也会不断地重置它并再次写入它(它不必像这样行事)。

为了解决这个问题,作者可以返回该self::$DB_Open属性(如果它确实存在)。

于 2013-02-04T12:50:39.140 回答