Du har i princip tre tillvägagångssätt för detta problem (av vilka jag kommer att eliminera en omedelbart):
- Ett bord per klass (det här är det jag kommer att ta bort);
- En posttyp med valfria kolumner; och
- En posttyp med en underordnad tabell beroende på vilken typ du går med i.
För enkelhetens skull rekommenderar jag generellt (2). Så när du väl har ditt bord:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(10),
name VARCHAR(100)
);
där typen kan vara 'AGENT' eller 'LEAD' (till exempel). Alternativt kan du använda en teckentypskoder. Du kan sedan börja fylla i tomrummen med objektmodellen:
- Du har en användarklass;
- Du har två barnklasser:Lead och Agent;
- De här barnen har en fast typ.
och det borde falla på plats ganska lätt.
När det gäller hur man laddar i ett uttalande, skulle jag använda någon form av fabrik. Förutsatt att dessa barebones-klasser:
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);
}
...
}
en fabrik kan se ut så här:
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]'");
}
}
Alternativt kan du låta fabriksmetoden vara en statisk metod på t.ex. User-klassen och/eller använda en uppslagstabell för typerna till klasser.
Att förorena klasserna med frågeresultatresursen på det sättet är kanske en tveksam design i den strikta OO-bemärkelsen, men det är enkelt och det fungerar.