简体   繁体   English

PHP OOP数据库设计

[英]PHP OOP database design

OK, this is just a quick question and I might take some slack for this but I'm just looking for a little guidance as I am completely self taught. 好吧,这只是一个简单的问题,我可能会为此稍微松一点,但我只是在寻找一些指导,因为我完全是自学成才。 I do a lot of reading and try to do a lot of building--I'd say I'm coming into a nice intermediate stage of php, mysql, and web knowledge in general--by no means advanced or overly confident--still learning. 我做了很多阅读并尝试做了很多建设 - 我说我正在进入一个很好的中间阶段的php,mysql和一般的网络知识 - 绝不是先进或过于自信 - 还在学习。

I'm really trying to tackle OOP in PHP and so I want to create a good lean database wrapper for MySQL, just MySQL, I'm most comfortable with MySQL and I dont see any reason to use any other database. 我真的想在PHP中解决OOP问题,所以我想为MySQL创建一个好的精益数据库包装器,只是MySQL,我对MySQL最熟悉,我没有看到任何其他数据库使用的理由。 I dont want to create any sort of portability in the design--I want it to be specific to my database; 我不想在设计中创建任何类型的可移植性 - 我希望它特定于我的数据库; so I dont want to use PDO. 所以我不想使用PDO。

So the question I have as of right now in the beginning is should I create a class that EXTENDS mysqli and then have create model classes for my database tables that extend that base database class? 因此,我现在开始的问题是,我应该创建一个扩展mysqli的类,然后为扩展该基础数据库类的数据库表创建模型类吗? so class->child = mysqli->DbBase->UsersModel ? 所以class-> child = mysqli-> DbBase-> UsersModel? This would require a lot of $this statements inside the class, would it not? 这需要在课堂内有很多$ this语句,不是吗?

Or should I instantiate a mysqli class and pass it to DbBase? 或者我应该实例化一个mysqli类并将其传递给DbBase?

Classes kind of represent things in the real world (or even imaginary "things"), right? 类是代表现实世界中的东西(甚至是想象中的“东西”),对吧? An instance of a DB represents a connection to that db. DB的实例表示与该数据库的连接。 Has a model something in common with a database connection? 有一个与数据库连接共同的模型吗? Not really. 并不是的。 I would suggest to include instances of your database class in those models classes you're going to write, because a model uses a database connection to access it's data but is not a kind of database connection. 我建议在你要编写的那些模型类中包含数据库类的实例,因为模型使用数据库连接来访问它的数据但不是一种数据库连接。

Concerning Mysqli <-> DBClass: That really depends on what you're trying to achieve with that DBClass - does it extend Mysqli with some extra functions or anything? 关于Mysqli < - > DBClass:这真的取决于你试图用这个DBClass实现的东西 - 它是否用一些额外的函数或任何东西扩展了Mysqli? If it doesn't, don't use inheritance there, otherwise you can use it. 如果没有,请不要在那里使用继承,否则可以使用它。


A very basic example, just to give you the idea: (it is actually a simplified but definitely not complete version of the ActiveRecord pattern) 一个非常基本的例子,只是为了给你一个想法:(它实际上是一个简化但绝对不完整的ActiveRecord模式版本)

abstract class DbTable {
    /* An instance of your DBClass (=Database Connection), to be used if no
     * other connection is specified. */
    protected static $_defaultDbAdapter = null;

    /* The db connection to be used by this instance. */
    protected $_dbAdapter = null;

    /* The name of the table in the database. */
    protected $_tableName = '';

    public static function setDefaultDbAdapter(DbClass $db) {
        self::$_defaultDbAdapter = $db;
    }

    public function setDbAdapter(DbClass $db) {
        $this->_dbAdapter = $db;
    }

    public function getDbAdapter() {
        if (null === $this->_dbAdapter) {
            $this->setDbAdapter(self::$_defaultDbAdapter);
        }
        return $this->_dbAdapter;
    }

    public function insert(array $data) { /*...*/ }
    public function update(array $data, $where) { /*...*/ }
    public function delete($where) { /*...*/ }
    public function select($where) { /* may e.g. return an array of DbTableRow childclass instances */ } 

    // ...
}

class Users extend DbTable {
    protected $_tableName = 'my_users_table';
}

abstract class DbTableRow {
    /* The row itself (may be not yet saved to the db!) */
    protected $_data = array();

    /* The row as it is in the database (to find differences, when calling save()). */
    protected $_cleanData = array();

    /* An instance of the table that this row belongs to. */
    protected $_table = null;

    public function __construct(DbTable $table, array $data = array()) { /*...*/ }
    public function save() { /* uses $this->_table->insert()/update() */ }
    public function __get($key) { /*...*/ }
    public function __set($key, $value) { /*...*/ }
    // ...
}

class User extends DbTableRow { }

Usage: 用法:

// Make a new connection to the database
$db = new DbClass('...'); // or whatever you name that class...

// Set this connection to be the default connection
DbTable::setDefaultDbAdapter($db);

// Create a new user
$users = new Users();
$user = new User($users);
$user->email = 'test@example.com';
$user->save();

If you're going to work with OOP, I'd strongly recommend using PDO, because it's the most updated and OO implementation of the MySQL library. 如果你打算使用OOP,我强烈建议使用PDO,因为它是MySQL库的最新和OO实现。 I don't think PDO-MySQL is any less MySQL-specific than MySQLi. 我认为PDO-MySQL不比MySQLi更具特定于MySQL。

In any case, you shouldn't extend PHP's class in this case, you should keep an object with the database connection as a property of your class. 在任何情况下,在这种情况下都不应该扩展PHP的类,您应该将具有数据库连接的对象作为类的属性。

You should also look into the Singleton design pattern, which is really useful in these cases. 您还应该研究Singleton设计模式,这在这些情况下非常有用。 Take a look at this post from today: Move out mysql connection into another class 从今天开始看看这篇文章: 将mysql连接移到另一个类中

If you really want to learn and understand OOP then I think you should start to learn some PHP frameworks (like Zend Framework) and read it's source codes. 如果你真的想学习和理解OOP,那么我认为你应该开始学习一些PHP框架(比如Zend Framework)并阅读它的源代码。 I learned lots of things from them. 我从中学到了很多东西。

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

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