По същество имате три подхода към този проблем (един от които ще премахна незабавно):
- Една таблица на клас (това е тази, която ще премахна);
- Тип запис с незадължителни колони; и
- Тип на запис с дъщерна таблица в зависимост от типа, към който се присъединявате.
За простота обикновено препоръчвам (2). Така че, след като имате вашата маса:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(10),
name VARCHAR(100)
);
където типът може да бъде "АГЕНТ" или "ВОД" (например). Като алтернатива можете да използвате кодове от един символен тип. След това можете да започнете да попълвате празните места с обектния модел:
- Имате родителски клас User;
- Имате два дъщерни класа:водещ и агент;
- Тези деца имат фиксиран тип.
и би трябвало да си дойде на мястото доста лесно.
Що се отнася до това как се зарежда в едно изявление, бих използвал някакъв фабричен. Ако приемем тези barebones класове:
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 смисъл, но е прост и работи.