V zásadě máte tři přístupy k tomuto problému (jeden z nich okamžitě odstraním):
- Jedna tabulka na třídu (to je ta, kterou vyřadím);
- Typ záznamu s volitelnými sloupci; a
- Typ záznamu s podřízenou tabulkou v závislosti na typu, ke kterému se připojíte.
Pro jednoduchost obecně doporučuji (2). Takže jakmile budete mít svůj stůl:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(10),
name VARCHAR(100)
);
kde typ může být 'AGENT' nebo 'LEAD' (například). Alternativně můžete použít kódy jednoho typu znaků. Poté můžete začít vyplňovat prázdná místa pomocí objektového modelu:
- Máte nadřazenou třídu uživatele;
- Máte dvě podřízené třídy:Lead a Agent;
- Tyto děti mají pevný typ.
a mělo by to docela snadno zapadnout.
Pokud jde o to, jak načíst v jednom výpisu, použil bych nějakou továrnu. Za předpokladu těchto barebones tříd:
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);
}
...
}
továrna může vypadat takto:
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]'");
}
}
Alternativně můžete mít tovární metodu jako statickou metodu, řekněme, na třídě User a/nebo použít vyhledávací tabulku pro typy do tříd.
Možná je takové znečištění tříd zdrojem výsledků dotazu sporné v nejpřísnějším OO smyslu, ale je to jednoduché a funguje to.