Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建PHP对象时重用数据库连接_Php_Mysql_Sql_Database_Oop - Fatal编程技术网

创建PHP对象时重用数据库连接

创建PHP对象时重用数据库连接,php,mysql,sql,database,oop,Php,Mysql,Sql,Database,Oop,在PHP中,我有两个类:数据库和项目 数据库包含连接属性和方法。例如,Database::Query可用于传递查询字符串等 项目是通用项目标识符。它是通过传递一个itemID来构建的,然后用于查询数据库中的其余项信息 在这种情况下,如果项对象需要数据库访问,那么创建它们的最佳实践是什么?使用以下语法创建每个对象是否正常: $item = new Item(12345, $db); 或者创建数据库对象并将其用于应用程序中创建的每个项目是否更好、可接受或可能,以便调用可以变成: $item = n

在PHP中,我有两个类:数据库项目

数据库包含连接属性和方法。例如,Database::Query可用于传递查询字符串等

项目是通用项目标识符。它是通过传递一个itemID来构建的,然后用于查询数据库中的其余项信息

在这种情况下,如果项对象需要数据库访问,那么创建它们的最佳实践是什么?使用以下语法创建每个对象是否正常:

$item = new Item(12345, $db);
或者创建数据库对象并将其用于应用程序中创建的每个项目是否更好、可接受或可能,以便调用可以变成:

$item = new Item(12345);

第二个看起来更干净(并且可以扩展,以便类似类型的对象也不需要$db插件),但是我正在寻找那些在这方面比我有更多经验的人的建议!谢谢

通常,数据库连接对象是全局的,或者可以全局访问。这对绝大多数应用程序都很有效

我会这样做(例如简化):


当然,在有些情况下,这不是最好的路线。与往常一样,它取决于应用程序的特定需求。

我建议对数据库连接使用单例模式。这实际上是最好的做法。因为您确实不需要访问数据库连接的实例

class Database_Instance
{
    private static $database;
    public static function getDatabaseObject() {
        if (!self::$db) {
            self::$db = new PDO( );
            }
        return self::$db;
    }
}

function callWhatSoEver()
{
    $connection = Database_Instance::getDatabaseObject();

}

有关singleton模式的更多信息,请参阅:

我建议大多数经验丰富的开发人员都倾向于依赖项注入方法,如第一个示例所示

为什么?

这主要是因为这允许您将依赖项注入的类与依赖项的实现解耦

考虑这个依赖注入示例:

Class some_class {
    protected $db;
    __construct($db) {
        if($db instanceof some_db_class === false) {
            throw new Exception('Improper parameter passed.');
        }
        $this->db = $db;
    } 

}
在这里,您可以传递任何类型的对象,只要它是
某个\u db\u类的实例
,它可以是该对象的子类,实现该类使用的相同方法。只要实现了这些方法,这对这个类并不重要(当然,除了检查其实例类型之外,您还可以检查传递的对象是否实现了特定的接口,或者代替检查其实例类型)

这意味着,例如,您可以传递一个模拟DB对象进行测试或类似的操作。只要实现了这些方法,类就不在乎了

现在考虑单点方法(或与类类似的DB实例化):

在这里,您已经将类与特定的数据库类紧密耦合。如果您想用模拟数据库实现来测试这个类,那么您需要修改这个类来测试它,这将是一件非常痛苦的事情


我甚至不会讨论使用
global
,因为这只是一种糟糕的做法,根本不应该考虑。

您可以将惰性初始化用于DB实例(它也可以针对mysqli进行调整)。-1:通常,这是任何应用程序中最有害的操作。否。不要使用全局声明。噢,请注意,对于绝大多数应用程序来说,这很好。@GrandmasterB肯定它“有效”,但任何人都不应该把它当作解决任何编程问题的建议方法。您需要一个类来理解全局范围中存在的某些特定变量名。这与封装的OOP原则背道而驰。当您更改变量名时会发生什么?突然之间,你不得不改变一堆类来更新这个变量名。你把你的类和应用程序的细节紧密地结合在一起,它没有商业上的理解。我相信你误读了这个例子$Load()方法中的db是本地的。示例中的GetDB()是全局可用的方法或函数的占位符,该方法或函数返回连接对象的实例。本地变量与名称无关。对象必须知道的唯一一件事是用于返回对db连接的引用的方法的名称。这比创建系统中使用的每个对象时需要传递对db连接的引用要简单得多,根本不是最佳实践。也许是10年前的事了。我相信依赖注入在很大程度上是这个行业发展的方式。这在PHP wspace中可能不太明显,因为真正的大型软件公司并没有广泛使用PHP。谢谢,非常感谢;)我建议只对某些_db_类进行类型提示,但如果这样做,则有一个例外:
InvalidArgumentException
;)@jimbo Yes类型提示是一个很好的建议,但如果您需要检查传递的对象是否实现了特定的接口,则没有帮助。。。这是最好的做事方式:-)
Class some_class {
    protected $db;
    __construct($db) {
        if($db instanceof some_db_class === false) {
            throw new Exception('Improper parameter passed.');
        }
        $this->db = $db;
    } 

}
Class some_class {
    protected $db;
    __construct() {
        $this->db = some_db_class::get_instance();
    } 
}