如何实例化我的数据库对象以在其他类中使用?

发布于 2024-10-21 02:59:57 字数 505 浏览 2 评论 0原文

我的应用程序遇到了架构问题。我已经推出了自己的(非常基本的)MVC,我的模型之一是数据库对象: class MySQLDatabase { }

我想在很多地方使用我的数据库对象,无需创建重复实例。在我的控制器中,我声明了 public $db; 并在 __construct { } 中声明了 $this->db = new MySQLDatabase;

问题:

如何在其他类中使用 $db ——它们也在控制器的 __construct { } 中实例化。我会在所有需要数据库连接的类的顶部声明 global $db 吗?

我习惯于在全局作用域中将全局变量声明为常规变量,然后使用 global 关键字来引用全局作用域...我不确定这是否适用于在其中声明的变量一个类(我的控制器。)

I've encountered an architectural issue with my application. I've rolled my own (very basic) MVC, and one of my models is a database object: class MySQLDatabase { }

There's a number of places in which I'd want to use my database object, without creating duplicate instances. Inside my controller, I have declared public $db; and within the __construct { } I have $this->db = new MySQLDatabase;

Question:

How do I use $db within my other classes--they're all instantiated within the controller's __construct { } as well... would I declare global $db at the top of all my classes that require database connectivity?

I'm used to global variables being declared in the global scope as regular variables, and then using the global keyword to reference the global scope... I'm not sure if that applies to variables declared within a class (my controller.)

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

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

发布评论

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

评论(6

战皆罪 2024-10-28 02:59:57

我会远离使用全局变量或单例模式(无论如何本质上都是全局的),并尝试寻找一些替代方案。另外,您正在谈论数据库连接,通过使用单例模式,您说永远不会有多个数据库连接,而在较小的应用程序中通常是这样,随着它们变得更大,您将无法容纳多个数据库连接连接。

一旦你制作了全局的东西,你就失去了它可以使用/修改的自动限制。使用 MVC 视图除了显示数据外不应该用于任何其他用途,通过使用全局/单例,开发人员可以不使用全局变量。然而,如果采用不同的设计,他们就没有这种选择。

您提到您已经创建了自己的 MVC 框架,所以我想您想要在其中使用它的类是您的模型?如果他们在其他地方,请纠正我。

如果您的模型从公共基类扩展,那么您可以将数据库对象作为静态变量传递给该类,该静态变量可以分配给构造中的任何新实例或在工厂方法中使用工厂方法。

这并不是说应该不惜一切代价避免全局变量或单例变量,但绝对要尝试考虑可能导致更简洁设计的替代方案。

如果您有兴趣,可以阅读以下有关单例模式的内容:

还有更多...

I would stay away from using globals or the Singleton pattern (which is essentially a global anyway), and try and find some alternatives. Additionally you are talking about a database connection, by using the Singleton pattern you are saying that there will never be more than one database connection, whilst that is generally true in smaller applications, as they grow larger you won't be able to accomodate multiple connections.

Once you make something global then you lose the automatic contraints of where it can be used/modified. Using MVC a view shouldn't be used for anything other than to display data, by using a global/singleton it is up to the developer to not make use of the globals. Whereas with a different design they don't have that option.

You mentioned you've created your own MVC framework, so I imagine the classes you want to use it in are your models? Correct me if they are anywhere else.

If your models extend from a common base class then you could pass your database object to that class as a static variable which can be assigned to any new instances in the construct or using a factory method in the factory method.

This isn't to say that globals or singletons should be avoided at all costs, but definitely try consider the alternatives that could lead to a neater design.

Here's some reading on the Singleton pattern if you're interested:

There are many more out there...

自找没趣 2024-10-28 02:59:57

如果我理解正确的话,您有一个实例化数据库对象的控制器,并且它还负责实例化其他类。如果是这样,您可以实现某种形式的依赖注入,或者在其他类的构造函数中传递 db 对象,或者创建一个 setter 方法。

关于该主题的一篇很好的博客文章:

http://www.potstuck。 com/2009/01/08/php-dependency-injection/

If I understand correctly you have a single controller that instantiates the database object and it also takes care of instantiating other classes. If so, you could implement some form of dependency injection either passing the db object in the constructor of the other classes or creating a setter method.

A good blog article on the subject:

http://www.potstuck.com/2009/01/08/php-dependency-injection/

滿滿的愛 2024-10-28 02:59:57

我认为您的处理方式是错误的,您不应该从控制器对数据库执行查询。

这意味着以下内容无效。

class ControllerIndex extends Controller
{
    public function index()
    {
        $this->db->selectAll("table");
    }
}

应该有一个层将控制器与数据库接口分开,这就是模型的用武之地。

您应该有一个模型文件夹,其中包含所采取的操作的类,例如用户、帖子、日志记录等。

class Users_Model extends Model
{
    public function getUser($id)
    {
    }
}

模型类应该是您的系统核心,并且应该扩展您的数据库类,这样在您的主控制器中您应该通过 ModelLoader 类加载模型。

例如:

class ModelLoader
{
    private $models = array();

    public function __get($model)
    {
        //load (/application/models/?.php) and initiate it here
        //Storing it in models array above
    }
}

然后在您的主控制器中:

class Controller
{
    private $model;

    public function __construct()
    {
        $this->model = new ModelLoader;
    }
}

这样您就可以将加载程序纳入子控制器的范围内:

class Controller_index extends Controller
{
    public function index()
    {
        $user = $this->model->users->getUser(22);
    }
}

希望这会有所帮助!

I Think you going about this the wrong way, you should not be performaing quesries to the database from you controller.

this means that the below is invalid.

class ControllerIndex extends Controller
{
    public function index()
    {
        $this->db->selectAll("table");
    }
}

There should be a layer that separates your controller from your database interface, this is where a Model comes in.

You should have a models folder that contain classes for actions taken such as users,posts,logging etc.

class Users_Model extends Model
{
    public function getUser($id)
    {
    }
}

The model class should be part of your system core, and should extend your Database Class, this way within your main controller you should be loading the models via the ModelLoader class.

for example:

class ModelLoader
{
    private $models = array();

    public function __get($model)
    {
        //load (/application/models/?.php) and initiate it here
        //Storing it in models array above
    }
}

Then in your main controller:

class Controller
{
    private $model;

    public function __construct()
    {
        $this->model = new ModelLoader;
    }
}

this way your bringing your loader into scope for the child controller:

class Controller_index extends Controller
{
    public function index()
    {
        $user = $this->model->users->getUser(22);
    }
}

Hope this helps!

幸福丶如此 2024-10-28 02:59:57

我认为您在这里需要的是数据库对象的单例:)

请参阅此处了解更多详细信息:http:// en.wikipedia.org/wiki/Singleton_pattern

使用 php 的示例单例进行编辑:(

<?php
class UniqueObject {

    private $_uniq = null;

    //private cause you don't want to instanciate the classic way
    private function __construct() {
        //...
    }

    //check if unique object exists or not, then return it
    public static function uniq() {
        if(!self::$_uniq)
            self::$_uniq = new UniqueObject();

        return self::$_uniq;
    }
}

//call your unique object whenever you need it
UniqueObject::uniq();
?>

已经晚了,我希望我没有做任何错误:))

I think what you need here is a singleton for you Database object :)

See here for more details : http://en.wikipedia.org/wiki/Singleton_pattern

Edit with sample singleton for php :

<?php
class UniqueObject {

    private $_uniq = null;

    //private cause you don't want to instanciate the classic way
    private function __construct() {
        //...
    }

    //check if unique object exists or not, then return it
    public static function uniq() {
        if(!self::$_uniq)
            self::$_uniq = new UniqueObject();

        return self::$_uniq;
    }
}

//call your unique object whenever you need it
UniqueObject::uniq();
?>

(it's late, i hope i didn't do any mistake :))

负佳期 2024-10-28 02:59:57

不要使用单例。显式传递数据要好得多。例如:

abstract class Controller {
  private static $conn; // could be an array for multiple connections
  final protected function getDBConnection() {
    if (!$this->conn) {
      $this->conn = new DBConnection();
    }
    return $this->conn;
  }
  abstract public function process(Request $r);
}

class HomePageController extends Controller {

  public function process(Request $r) {
    $results = $this->getDBConnection()->query('SELECT stuff FROM foo;');
    // do stuff with $results
  }

}

您还可以传递一个显式模型对象,例如代表用户的模型对象,但这对于您的项目来说可能有点过分了。

Don't use singletons. It's much better to explicitly pass around data. For example:

abstract class Controller {
  private static $conn; // could be an array for multiple connections
  final protected function getDBConnection() {
    if (!$this->conn) {
      $this->conn = new DBConnection();
    }
    return $this->conn;
  }
  abstract public function process(Request $r);
}

class HomePageController extends Controller {

  public function process(Request $r) {
    $results = $this->getDBConnection()->query('SELECT stuff FROM foo;');
    // do stuff with $results
  }

}

You could also have an explicit model object you pass around, e.g. the one that represents the user, but that may be overkill for your project.

提赋 2024-10-28 02:59:57

您需要使用单例模式。他们在 php 文档中给出了示例

<?php
class Example
{
    // Hold an instance of the class
    private static $instance;

    // A private constructor; prevents direct creation of object
    private function __construct() 
    {
        echo 'I am constructed';
    }

    // The singleton method
    public static function singleton() 
    {
        if (!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c;
        }

        return self::$instance;
    }

    // Example method
    public function bark()
    {
        echo 'Woof!';
    }

    // Prevent users to clone the instance
    public function __clone()
    {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }

}

?>

http://php.net/manual/en/语言.oop5.patterns.php

You'll need to use a singleton pattern. They give examples in the php docs

<?php
class Example
{
    // Hold an instance of the class
    private static $instance;

    // A private constructor; prevents direct creation of object
    private function __construct() 
    {
        echo 'I am constructed';
    }

    // The singleton method
    public static function singleton() 
    {
        if (!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c;
        }

        return self::$instance;
    }

    // Example method
    public function bark()
    {
        echo 'Woof!';
    }

    // Prevent users to clone the instance
    public function __clone()
    {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }

}

?>

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

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