在PHP中,我有两个类:数据库和项目。
数据库包含连接属性和方法。例如, Database :: Query 可用于传递查询字符串等
项目是通用项目标识符。它是通过传递 itemID 构建的,然后用于在数据库中查询其余的项目信息。
在这种情况下,如果需要数据库访问,创建Item对象的最佳做法是什么?使用以下语法创建每个语句是否正常:
$item = new Item(12345, $db);
或者更好,可以接受或者可以创建数据库对象并将其用于应用程序中创建的每个项目,以便调用可以变为:
$item = new Item(12345);
第二个似乎更清晰(并且可以扩展,以便类似类型的对象也不需要$ db插件),但我正在寻找那些比我更有经验的人的建议!谢谢!
答案 0 :(得分:2)
我建议大多数经验丰富的开发人员都倾向于依赖注入的方法,如第一个例子所示。
为什么?
很大程度上是因为这允许您从依赖项的实现中解除向其注入依赖项的类。
所以请考虑这个依赖注入示例:
Class some_class {
protected $db;
__construct($db) {
if($db instanceof some_db_class === false) {
throw new Exception('Improper parameter passed.');
}
$this->db = $db;
}
}
在这里你可以传递任何类型的对象,只要它是some_db_class
的一个实例,它就可以是该对象的子类,它实现了这个类使用的相同方法。只要方法被实现,这对这个类来说无关紧要(当然,除了检查其实例类型之外,您当然也可以检查传递的对象是否实现了特定的接口。)
这意味着,例如,您可以传递模拟数据库对象进行测试或类似的事情。只要方法得到实施,该课程就不在乎。
现在考虑单例方法(或类与类似的DB实例化):
Class some_class {
protected $db;
__construct() {
$this->db = some_db_class::get_instance();
}
}
在这里,您将类紧密耦合到特定的数据库类。如果你想用模拟数据库实现来测试这个类,那么你需要修改这个类就会非常痛苦。
我甚至不会讨论使用global
,因为这只是不好的做法而且根本不应该考虑。
答案 1 :(得分:-3)
我建议使用Singleton Pattern进行数据库连接。这实际上是最好的做法。因为你真的不需要数据库连接的实例。
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();
}
有关单例模式的详细信息,请参阅:http://en.wikipedia.org/wiki/Singleton_pattern
答案 2 :(得分:-4)
通常,数据库连接对象是全局的,或者可以全局访问。这适用于绝大多数应用程序。
我这样做(简化为例):
$db = connect_to_db();
function GetDB()
{
global $db;
return $db
}
//inside the item object
function Load( $id)
{
$db = GetDB();
$db->query(..);
}
当然,这不是最好的路线。与往常一样,它取决于您的应用程序的特定需求。