所以我知道不应该问他们标题中“最好的”问题,但是真的......你应该怎么做?
我们有一个数据库类,例如,一个用户类。用户类将获得诸如create()和update()之类的方法,这些方法需要执行数据库操作。
据我所知,有两个主要选项,在每个__construct()中传递数据库对象或使数据库类静态。
(关于OOP +数据库驱动的网站的任何其他提示也很感激)
答案 0 :(得分:2)
这里一个非常常见的模式是使数据库类成为单例构造,然后将其传递给每个对象构造函数(称为Dependency Injection)。
使数据库对象成为单例的目的是确保每个页面加载只进行一次连接。如果由于某种原因需要多个连接,您可能希望以不同的方式执行此操作。通过构造函数传递它非常重要,而不是在不相关的类中创建数据库对象,以便您可以更轻松地测试和调试代码。
// Basic singleton pattern for DB class
class DB
{
// Connection is a static property
private static $connection;
// Constructor is a private method so the class can't be directly instantiated with `new`
private function __construct() {}
// A private connect() method connects to your database and returns the connection object/resource
private static function connect() {
// use PDO, or MySQLi
$conn = new mysqli(...);
// Error checking, etc
return $conn;
}
// Static method retrieves existing connection or creates a new one if it doesn't exist
// via the connect() method
public static function get_connection() {
if (!self::$connection) {
self::$connection = self::connect();
// This could even call new mysqli() or new PDO() directly and skip the connect() method
// self::$connection = new mysqli(...);
}
return self::$connection;
}
}
class Other_Class
{
// accepts a DB in constructor
public function __construct($database) {
//stuff
}
}
// Database is created by calling the static method get_connetion()
$db = DB::get_connection();
$otherclass = new Other_Class($db);
// Later, to retrieve the connection again, if you don't use the variable $db
// calling DB::get_connection() returns the same connection as before since it already exists
$otherclass2 = new Other_Class(DB::get_connection());
另一种方法是创建数据库类直接扩展 mysqli
或PDO
。在这种情况下,__construct()
方法将对象提供给getConnect()
,如
public static function get_connection() {
if (!self::$connection) {
self::$connection = new self(/* params to constructor */);
}
return self::$connection;
}
答案 1 :(得分:1)
那么,你可以做的是将数据库访问层放在一个对象中,然后传递给你的对象,尊重控制模式的反转。
如果你想向这个方向挖掘一下,看一下依赖注入(DI):http://en.wikipedia.org/wiki/Dependency_injection
拥有单身通常是一个坏主意,因为在测试代码时最终会遇到问题。
答案 2 :(得分:1)
在诸如User之类的模型类中具有数据库访问逻辑违反了关注点分离原则。通常DAO(数据访问对象)处理与数据库相关的问题。
有一些ORM框架,比如Hibernate,可以很好地处理OO和关系模型之间的不匹配,可能会节省大量的手工工作。
答案 3 :(得分:1)
我真的很惊讶,没有人这么说,但在这里:ORM。
如果您选择的武器是PHP,那么主要选项是Propel和Doctrine。他们都有很多优点和缺点,但毫无疑问他们是强大的。举个例子,来自Propel(我个人最喜欢的)用户手册:
// retrieve a record from a database
$book = BookQuery::create()->findPK(123);
// modify. Don't worry about escaping
$book->setName('Don\'t be Hax0red!');
// persist the modification to the database
$book->save();
$books = BookQuery::create() // retrieve all books...
->filterByPublishYear(2009) // ... published in 2009
->orderByTitle() // ... ordered by title
->joinWith('Book.Author') // ... with their author
->find();
foreach($books as $book) {
echo $book->getAuthor()->getFullName();
}
你不会得到比这更多的OO!
他们会为你处理很多事情,从数据库供应商那里抽象你的数据。也就是说,您应该能够(相对轻松地)从MySQL移动到SQL Server,如果您正在为Web应用程序构建自己的工具,那么能够适应不同环境是一件非常重要的事情。
希望我能帮忙!
答案 4 :(得分:0)
嘿,看看ORM吧。让他们为你努力工作?流利的nhibernate或microsofts实体框架。
我可能会误解你的问题。对不起,如果是这样