我有一个名为"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
}
想法1似乎是最有效的,或者最少的DB调用,但比想法2更复杂,更不直接。
我更喜欢第二个想法,但我担心它的可扩展性,因为每个函数都要调用DB。
思想我建议您学习DataMapper模式。基本思想是这样的:
假设(为了方便示例)您有一个用于处理书籍的应用程序的MVC结构。
- 有一个模型
- 模型处理未知数量的
Book
实例(图书馆中的许多书)。
每本书:- 知道自己的一切(作者、出版日期、语言……)等)
- 没有知道它存储在哪里或者数据来自哪里
- 可以与数据库中的表相关,但包含来自多个表的信息
然后你有一个 - 模型在构造函数中接收(实现预定义接口)
- 知道如何(以及在哪里)存储
Book
对象,以及如何将数据读取到它们 - 可以切换到不同的对象,如果存储介质改变
- 如果它与DB一起工作,那么它在构造函数中已经请求了一个DB对象(如PDO)
- 有
store( Book $book )
和retrieve( Book $book )
方法用于保存图书数据,或从存储 获取新信息
Library
负责管理不同书籍的领域逻辑是有意义的。BookMapper
类的实例,其中:这就是我要做的。
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...
}
这样你就可以很容易地使用它来获取其他信息,也只是创建一个新的类,它的函数来检索/删除/等信息
首先,用户对象意味着保存用户数据,所以我建议方法#1,方法#2更像是一个模型对象,发送命令来获取数据。
现在,您可以在一个查询中将用户行自动映射到对象,例如:
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
我认为如果你要实现你自己的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 . "'/>";
}
}
您试图归档的是ORM(对象-关系映射器)的功能。使用一个可能是有益的,而不是自己做。
如果你想自己做,我会选择惰性加载。这是介于你的两个想法之间的一点。在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()
函数,该函数将丢弃所做的所有更改。
我建议你使用像Yii这样的php框架。
http://www.yiiframework.com/它有很好的功能在类和数据库之间进行交互。如果你真的想自己做这个,你也可以从这里得到一些灵感。