PHP Singleton 扩展类

发布于 2024-12-08 15:53:11 字数 445 浏览 0 评论 0原文

我是 OOP (PHP) 新手,刚刚接触了设计模式 - singleton。 我找到了一个使用 mysqli (单例类)的数据库类。我向其中添加了一些自定义方法(insert_id()query()fetch_result() 等)。

然后我创建了一个名为 UserTools 的新类,我想扩展数据库类以使用我之前创建的方法(query()fetch_result() 等)。 但我收到这个错误:

致命错误:从 (...) 中的无效上下文调用私有 Database::__construct() 当我尝试创建新类的实例(用户工具)时。

我应该怎么办?这是一个正确的结构吗?

I am new to OOP (PHP) and just met the design pattern - singleton.
I have found a DB class which uses mysqli (singleton class). I have added some custom methods to it (insert_id(), query(), fetch_result(), etc).

Then I created a new class called UserTools and I want to extend the database class to use the methods I've created previously (query(), fetch_result(), etc).
But I get this error:

Fatal error: Call to private Database::__construct() from invalid context in (...)
when I try to create instance of the new class (User Tools).

What should I do? Is it a right structure?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

十雾 2024-12-15 15:53:11

有多种方法可以实现您想要的目标。

一种是:

class UserTools {
    private $db;
    function __construct() {
        $this->db = Database::db_connect();
    }

    function login() { /* ... */}
}

虽然最好像这样直接将数据库实例传递给构造函数:

class UserTools {
    private $db;
    function __construct($db) {
        $this->db = $db;
    }

    function login() { /* ... */}
}

// Usage 
$userTools = new UserTools(Database::db_connect());

如果你真的很懒,你可以修改你的数据库类并将构造函数公开:

class Database {
    /* ... */
    public function __construct(){/* ... */}
    /* ... */
}

class UserTools extends Database {/* ... */}

但我真的不鼓励你使用后一种。这是非常糟糕的代码,从逻辑角度来看没有意义。您的 UserTools 类使用数据库实例。它不是数据库。

There are several way to achieve what you want.

One would be :

class UserTools {
    private $db;
    function __construct() {
        $this->db = Database::db_connect();
    }

    function login() { /* ... */}
}

Although it would be better to directly pass the database instance to the constructor like this :

class UserTools {
    private $db;
    function __construct($db) {
        $this->db = $db;
    }

    function login() { /* ... */}
}

// Usage 
$userTools = new UserTools(Database::db_connect());

If you're really lazy you could just modify your database class and make the constructor public :

class Database {
    /* ... */
    public function __construct(){/* ... */}
    /* ... */
}

class UserTools extends Database {/* ... */}

But I really discourage you to use the latter one. It's really bad code and it doesn't make sense in a logical point of view. Your UserTools class use a database instance. It is not a database.

狂之美人 2024-12-15 15:53:11

据我了解,只有 protectedpublic 方法和变量是通过扩展继承的,而不是私有的。尝试将您的方法/变量从 private 更改为 protectedpublic 对所有人都可见。

有关详细信息,请参阅:PHP 可见性(手动)

编辑

了解单例模式。它被称为“单例”,因为只需要一个类的一个实例。因此,大多数实现单例模式的类将构造函数定义为私有,以限制您创建多个构造函数。

为了创建单例的实例,大多数类都定义某种公共的getInstance静态方法。此公共方法调用私有构造函数,该构造函数可能会设置指示该类已实例化的标志,以防止进一步尝试实例化该类。 getInstance 方法返回调用构造函数的结果,本质上是类的实例。

It is my understanding that only protected and public methods and variables are inherited through extension, not private ones. Try changing your methods/variables from private to protected. public ones are visible to all.

For more information, See: PHP Visibility (Manual)

Edit

Understand the Singleton pattern. It is called 'singleton' because only one instance of a class is expected. Because of this, most classes implementing the singleton pattern define the constructor as private to restrict you from creating more than one.

To create an instance of a singleton, most classes define some kind of getInstance static method, which is public. This public method calls the private constructor, which probably sets flags indiciating that the class has been instantiated in order to prevent further attempts to instantiate the class. The getInstance method returns the results of calling the constructor, essentially the instance of the class.

叫嚣ゝ 2024-12-15 15:53:11

您可以编写类似于

class UserTools extends DB {
    ....
}

PHP 继承的快速示例:

class A {
   public $a;
   public function set_a($new_a) { $this->a = $new_a; return $this; }
   public function get_a() { return $this->a; }
}

class B extends A {
   public $b;
   public function set_b($new_b) { $this->b = $new_b; return $this; }
   public function get_b() { return $this->b; }
}

$objb = new B();

$objb->set_a("Some Value")->get_a(); //Some Value

You could write something like

class UserTools extends DB {
    ....
}

A quick example on inheritance in PHP:

class A {
   public $a;
   public function set_a($new_a) { $this->a = $new_a; return $this; }
   public function get_a() { return $this->a; }
}

class B extends A {
   public $b;
   public function set_b($new_b) { $this->b = $new_b; return $this; }
   public function get_b() { return $this->b; }
}

$objb = new B();

$objb->set_a("Some Value")->get_a(); //Some Value
薔薇婲 2024-12-15 15:53:11

在大多数情况下,单例模式通过将构造函数定义为私有(即私有函数__construct())来防止实例化Singleton类。

因此,如果您尝试实例化您的自定义类或您要扩展的原始类,您将收到上面的消息。您应该创建一个不同的类,或者定义并使用您的静态函数(例如public static function query($sql, $dbconnection))。

请参阅http://php.net/manual/en/language.oop5.patterns。 php

The singleton pattern in most cases prevents instantiating the Singleton class by defining the constructor as private (ie private function __construct()).

So if you try to instantiate either your custom class or the original one that you're extending you will get the message above. You should either create a different class or define and use your function as static (eg public static function query($sql, $dbconnection)).

See http://php.net/manual/en/language.oop5.patterns.php

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文