简体   繁体   English

我应该如何在其他课程中使用数据库课程?

[英]How should I use my database class in other class?

I have one database wrapper class. 我有一个数据库包装器类。 How should I use this class object to execute query in other class? 我应该如何使用该类对象在其他类中执行查询?

$liveresellerdb=new Database('host','user','spswd','db');
$fetch = $liveresellerdb->getResult($select_resellerData);

How should I include the database object in my one class? 我应该如何在一个类中包括数据库对象?

Class one 
{
    function a (){
       $sql="select * from table ";
       //how should i execute here my query i mean to say 
       //every time i can't create the new object 
       // i want to know the good method by which i just execute the query by
       // giving the database name    
    }
}

I'd advise against the Singleton pattern (using static members is a variation of this pattern) and use Dependency Injection instead. 我建议不要使用Singleton模式(使用静态成员是此模式的变体),而应使用依赖注入。 This means that you pass the database object to your service (the class that uses the connection) through the constructor. 这意味着您通过构造函数将数据库对象传递给服务(使用连接的类)。

Here is an example. 这是一个例子。

class UserFinder
{
    private $db;

    public function __construct(Database $db)
    {
        $this->db = $db;
    }

    public function findAllActive()
    {
        $sql = 'SELECT * FROM users WHERE active = 1';

        return $this->db->executeAndFetchAll($sql);
    }
}

$db = new Database($host, ...);
$finder = new UserFinder($db);

$users = $finder->findAllActive();

This ensures that you are not bound to a specific implementation of the Database class (you could make a sub-class) and will allow you to create separate UserFinder s with separate Database instances. 这样可以确保您不受数据库类的特定实现约束(可以创建子类),并允许您使用单独的Database实例创建单独的UserFinder It will also make it easier to write tests for your application because you have less dependencies, which are not hidden and also replaceable. 这也将使为应用程序编写测试变得更加容易,因为您的依赖项更少,这些依赖项不是隐藏的,也是可替换的。

In short: Use dependency injection. 简而言之:使用依赖注入。

Since global variables are dirty (you always need the global $var; statement), the easiest solution is to store them in a static member of a class, eg Database::$db . 由于全局变量是脏的(您始终需要global $var;语句),所以最简单的解决方案是将它们存储在类的静态成员中,例如Database::$db

Another solution (in a proper OOP environment) would be passing the database instance to the classes - in your code it would be the constructor of one which accepted the instance and then stored in a private member variable. 另一个解决方案(在适当的OOP环境中)是将数据库实例传递给类-在您的代码中,它将是one接受实例并存储在私有成员变量中的实例的构造函数。

Maybe, you should think about implementing your Database class according to a Singleton Pattern . 也许您应该考虑根据Singleton Pattern实现您的Database类。


Updated (according to comment below): 更新(根据下面的评论):

Ok. 好。 I have only one suggestion here (except passing object via method's parameters and Dependency Injection, described in igorw's comment )... 我在这里只有一个建议(除了通过方法的参数和Dependency Injection传递对象,如在igorw的注释中所述 )...

Dependency Injection is a good way, but this case you - I suppose - have some small amount of databases, so it can be better to save them all in some static private array and get by keys. 依赖注入是一种好方法,但是,我想,这种情况下您的数据库数量很少,因此最好将它们全部保存在某个静态私有数组中并通过键来获取。

So you will have only one public static method getInstance($key) and keys can be stored as some predefined constants (to avoid "spelling" errors). 因此,您只有一个公共静态方法getInstance($key)并且可以将键存储为一些预定义的常量(以避免“拼写”错误)。

This way you don't require initialization at all ( getInstance($key) can create new Database objects with necessary parameters [passed to constructor] depending on the $key parameter). 这样,您根本不需要初始化( getInstance($key)可以创建具有必要参数的新数据库对象[传递给构造函数],具体取决于$ key参数)。 Dependency Injection looks better in general, but in some particular cases this way can be easier-to-use. 通常,依赖注入看起来更好,但是在某些特定情况下,这种方式更易于使用。

Could be ok to have a Db setAdapter method that store database connections in a static property by name: 可以有一个Db setAdapter方法,该方法通过名称将数据库连接存储在静态属性中:

Db::setAdapter('db1', 'mysql:host=localhost;dbname=' . $dbname, $user, $pass);
Db::setAdapter('db2', 'mysql:host=localhost;dbname=' . $dbname2, $user2, $pass2);

Then a getAdapter method that will return a database connection when needed: 然后是一个getAdapter方法,该方法将在需要时返回数据库连接:

Db::getAdapter(); // return the default one
Db::getAdapter('db2'); // return an instance by its name

Behind the scenes you could implement a lazy connection too. 在后台,您也可以实现惰性连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM