Du har grundlæggende tre tilgange til dette problem (hvoraf den ene vil fjerne med det samme):
- Et bord pr. klasse (dette er den, jeg vil eliminere);
- En posttype med valgfrie kolonner; og
- En posttype med en undertabel afhængigt af den type, du tilslutter dig.
For nemheds skyld anbefaler jeg generelt (2). Så når først du har dit bord:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(10),
name VARCHAR(100)
);
hvor typen kan være 'AGENT' eller 'LEAD' (for eksempel). Alternativt kan du bruge koder af en karaktertype. Du kan derefter begynde at udfylde de tomme felter med objektmodellen:
- Du har en brugerforælderklasse;
- Du har to børneklasser:Lead og Agent;
- Disse børn har en fast type.
og det burde falde på plads ret nemt.
Med hensyn til, hvordan man indlæser i en erklæring, ville jeg bruge en slags fabrik. Forudsat disse 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 kunne se sådan ud:
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 have fabriksmetoden til at være en statisk metode på f.eks. brugerklassen og/eller bruge en opslagstabel for typerne til klasser.
Måske at forurene klasserne med forespørgselsresultatressourcen på den måde er et tvivlsomt design i den strengeste OO-forstand, men det er enkelt og det virker.