什么是DB对象交互的其他PHP类设计?

时间:2011-04-28 18:07:01

标签: php class-design

我有一个名为“User”的表,用于保存用户信息。我将调用我的用户类并创建一个用户对象,以便我可以获取该用户所需的任何信息。

我一直在为我的网站使用以下类和它们的混合,但是从来没有真正满意它们主要是因为我不确定其他开发人员如何处理这种情况以及是否有更好的解决方案。以下是我一直在使用的一些方法,我很想知道其他开发人员是如何做的。

想法#1

class User
{ 
   //public user

   public function __construct()
   {
          //get user - queries table and returns all fields in array

   }

   //get name function - references user array and returns name
   //set name function - sets new name in array 

   //commit function - commits array to db (saves changes)
}

想法#2

class User
    { 
       //user id

       public function __construct(user id)
       {
              //set user id

       }

       //get name function - calls db directly and returns name
       //set name function - calls db directly and sets name

       //commit function - commits array to db saves changes
    }

Idea#1似乎是最有效或最少量的数据库调用,但比Idea#2更复杂,更简单。

我更喜欢2号想法,但我担心它的可扩展性,因为每个函数都会调用DB。

思想

6 个答案:

答案 0 :(得分:2)

我建议您了解DataMapper模式。基本想法是这样的:

让我们说(为了举例)你有一个处理书籍的应用程序的MVC结构。

  • 有一个模型 Library 是有意义的,它负责管理不同书籍的域逻辑。
  • 该模型处理未知数量的 Book 个实例(图书馆中的许多图书)。
    每本书
    • 了解自己的一切(作者,出版日期,语言......等)
    • 没有想法存储它的位置或数据来自哪里
    • 可以与Database中的表相关,但包含来自多个表的信息
  • 然后你有一个 BookMapper 类的实例,
    • 模型在构造函数中接收(实现预定义接口)
    • 知道如何(以及在​​何处)存储Book个对象,以及如何将数据读入其中
    • 如果存储介质发生变化,
    • 可以切换到其他对象
    • 如果它适用于DB,那么它在构造函数中已经请求了一个DB对象(如PDO)
    • 有方法store( Book $book )retrieve( Book $book )用于保存图书数据或从存储中获取新信息

我会这样做..

答案 1 :(得分:1)

如下:

class Db
{
    function __construct()
    {
        $this->engine = DB_ENGINE;
        $this->dbname = DB_NAME;
        $this->host = DB_HOST;
        $this->username = DB_USERNAME;
        $this->password = DB_PASSWORD;

        $this->connect();
    }

    function connect()
    {
        $this->db = new PDO($this->engine.':host='.$this->host.';dbname='.$this->dbname, $this->username, $this->password);
    }
}

class Table extends Db
{
    protected $from = null;

    function __construct()
    {
        parent::__construct();
    }

    function select($columns, $where, $order, $offset, $limit)
    {
    }

    function update($where, $data)
    {
    }

    function delete($where)
    {
    }

    etc...

}

class User extends Table
{
    function __construct()
    {
        parent::__construct();
        $this->from = 'blog';
    }

    function get_user()
    {
        $this->select(params);
    }

    function get_user_count()
    {
    }

    etc...
}

通过这种方式,您可以轻松地使用它来获取其他信息,只需创建一个新类,其中包含检索/删除/等信息的函数。

答案 2 :(得分:0)

首先,用户对象用于保存用户数据,因此我建议使用方法#1,方法#2更像是一个发送命令以获取数据的amodel对象。

现在,您可以在一个查询中自动将用户行映射到对象,例如:

class User
{
    //Predefine Here
    public $id;
    public $username;
    public $password;
    public $email;
    public $hash;

    public function profileLink()
    {
         return sprintf('<a href="/profile/%s">%s</a>',$this->id,$this->username);
    }
}

//Fetch the results

$result = $sth->fetchAll(PDO::FETCH_CLASS, "User");
$userObjects = array();
foreach($result as $user)
{
    $userObjects[] = $user;
}

//Now you can use like so:

echo $userObjects[2]->profileLink();

所以我的另一个答案是:PDO PHP Fetch Class

答案 3 :(得分:0)

我认为如果您要实现自己的User类,那么它应该类似于以下内容:

class User {
    private $UserID;
    private $Username;
    private $AvatarImg;
    // ... First Name, Last Name, ALL other user information that you store in the DB.

    function __construct( $uid ) {
        // Populate all private members from the DB for the given user id.
    }

    function update( $assocArrayOfValues ) {
        // Commit these values to the Db and Update the private members.
    }

    // All Associated get functions ( getName, getUID, getUsername etc )
    // Any other specialty functions you may want, e.g...
    function getAvatar() {
        return "<img src = '" . $this->AvatarImg . "'/>";
    }

}

答案 4 :(得分:0)

您尝试归档的是ORM(Object-Relational-Mapper)的功能。使用一个而不是自己动手可能是有益的。

如果你想自己做,我会去懒惰。这是你的两个想法之间的一点点。在PHP中它看起来像这样:

class User
{ 
    private $id; // depends on your application, could also be a string
    private $dirty;
    private $loaded;

    private $properties;

    public function __construct($user_id)
    {
        $this->id = $user_id;
    }

    public function __destruct()
    {
        if ($this->dirty) {
            // commit to DB
        }
    }

    public function __get($name)
    {
        if (!$loaded)
        {
            $this->loadFromDb();
        }
        // error-handling if the key does not exist is missing here!
        return $this->properties[$name];
    }

    public function __set($name, $value)
    {
        // May be required to load the data here...

        // error-handling if the key does not exist is missing here!
        $properties[$name] = $value;
        $this->dirty = true;
    }

    private function loadFromDb()
    {
        // query data from db and store it in properties
    }
}

这种设计的优点是,如果你构造最终你不需要的对象,那么还没有任何东西触及数据库。还要注意解构过程中的提交。

如果您有时加载集合,那么让函数从DB加载一堆行并在创建对象时将行作为参数传递给构造函数可能会很有用。如果你自己构造每个对象,这只需要一个查询而不是几百个查询。

作为进一步的增强功能,您可以提供User::reset()功能,该功能会丢弃所做的所有更改。

答案 5 :(得分:-1)

我建议你使用像Yii这样的PHP框架。

http://www.yiiframework.com/

它具有很好的功能,可以在类和数据库之间进行交互。 如果你真的想自己做这件事,你也可以获得一些灵感。