इस समस्या के लिए आपके पास मूल रूप से तीन दृष्टिकोण हैं (जिनमें से एक मैं तुरंत समाप्त कर दूंगा):
- प्रति कक्षा एक टेबल (यह वह है जिसे मैं खत्म कर दूंगा);
- वैकल्पिक कॉलम के साथ एक रिकॉर्ड प्रकार; और
- चाइल्ड टेबल के साथ एक रिकॉर्ड प्रकार, जिस प्रकार से आप जुड़ते हैं उसके आधार पर।
सादगी के लिए मैं आमतौर पर (2) की सलाह देता हूं। तो एक बार जब आपके पास आपकी टेबल हो:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(10),
name VARCHAR(100)
);
जहां प्रकार 'एजेंट' या 'लीड' हो सकता है (उदाहरण के लिए)। वैकल्पिक रूप से आप एक वर्ण प्रकार के कोड का उपयोग कर सकते हैं। फिर आप रिक्त स्थान को ऑब्जेक्ट मॉडल से भरना शुरू कर सकते हैं:
- आपके पास उपयोगकर्ता अभिभावक वर्ग है;
- आपके पास दो चाइल्ड क्लास हैं:लीड और एजेंट;
- उन बच्चों का एक निश्चित प्रकार होता है।
और यह काफी आसानी से अपने स्थान पर आ जाना चाहिए।
एक कथन में कैसे लोड किया जाए, इसके लिए मैं किसी प्रकार की फैक्ट्री का उपयोग करूंगा। इन बेयरबोन क्लासेस को मानते हुए:
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]'");
}
}
वैकल्पिक रूप से, आप उपयोगकर्ता वर्ग पर फ़ैक्टरी विधि एक स्थिर विधि हो सकते हैं और/या कक्षाओं के प्रकारों के लिए लुकअप तालिका का उपयोग कर सकते हैं।
शायद इस तरह के क्वेरी परिणाम संसाधन के साथ कक्षाओं को प्रदूषित करना सख्त ओओ अर्थ में एक संदिग्ध डिजाइन है, लेकिन यह आसान है और यह काम करता है।