基本上,您可以使用三种方法来解决此问题(我将立即消除其中一种方法):
- 每个班级一张桌子(这是我要消除的一张桌子);
- 具有可选列的记录类型;和
- 具有子表的记录类型,具体取决于您加入的类型。
为简单起见,我通常推荐(2)。所以一旦你有了桌子:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(10),
name VARCHAR(100)
);
其中类型可以是“AGENT”或“LEAD”(例如)。或者,您可以使用一种字符类型代码。然后您可以开始使用对象模型填充空白:
- 你有一个 User 父类;
- 您有两个子类:Lead 和 Agent;
- 这些孩子都有固定的类型。
它应该很容易就位。
至于如何在一条语句中加载,我会使用某种工厂。假设这些准系统类:
class User {
private $name;
private $type;
protected __construct($query) {
$this->type = $query['type'];
$this->name = $query['name'];
}
...
}
class Agent {
private $agency;
public __construct($query) {
parent::constructor($query);
$this->agency = $query['agency'];
}
...
}
class Lead {
public __consruct($query) {
parent::constructor($query);
}
...
}
工厂可能看起来像这样:
public function loadUserById($id) {
$id = mysql_real_escape_string($id); // just in case
$sql = "SELECT * FROM user WHERE id = $id";
$query = mysql_query($sql);
if (!query) {
die("Error executing $sql - " . mysql_error());
}
if ($query['type'] == 'AGENT') {
return new Agent($query);
} else if ($query['type'] == 'LEAD') {
return new Lead($query);
} else {
die("Unknown user type '$query[type]'");
}
}
或者,您可以让工厂方法成为 User 类上的静态方法和/或使用类类型的查找表。
也许从最严格的 OO 意义上来说,用查询结果资源污染类是一个有问题的设计,但它很简单并且有效。