2009-07-27 16 views
6

तो मैं PHP के साथ अच्छी ऑब्जेक्ट उन्मुख प्रोग्रामिंग तकनीकों को अपनाने की कोशिश कर रहा हूं। मेरी परियोजनाओं के अधिकांश (सभी पढ़ें) में एक MySQL डेटाबेस शामिल है। मेरी तत्काल समस्या उन उपयोगकर्ताओं के मॉडल से संबंधित है जिन्हें मुझे विकसित करने की आवश्यकता है।PHP विरासत और MySQL

मेरी वर्तमान परियोजना में एजेंट और लीड्स हैं। एजेंट और लीड दोनों ही एक ही जानकारी वाले उपयोगकर्ता हैं। तो, जाहिर है, मैं एक वर्ग एजेंट चाहता हूं और एक वर्ग एक आम वर्ग उपयोगकर्ताओं का विस्तार करने के लिए नेतृत्व करता है। अब, मेरा प्रश्न निम्नानुसार है:

इन वस्तुओं को लोड करने के लिए एसक्यूएल को सर्वोत्तम तरीके से कैसे संभाला जाना चाहिए? जब मैं एजेंट या लीड को तुरंत चालू करता हूं तो मैं एकाधिक SQL कथन निष्पादित नहीं करना चाहता हूं। हालांकि, तर्क मुझे बताता है कि जब उपयोगकर्ता कन्स्ट्रक्टर को निकाल दिया जाता है, तो इसे एजेंटों और लीड्स (उपयोगकर्ता नाम, पासवर्ड, ईमेल, संपर्क जानकारी इत्यादि) के बीच सामान्य जानकारी लोड करने के लिए SQL कथन निष्पादित करना चाहिए। तर्क मुझे यह भी बताता है कि जब एजेंट या लीड कन्स्ट्रक्टर निकाल दिया जाता है, तो मैं एजेंटों या लीड्स क्लास के लिए अद्वितीय डेटा लोड करने के लिए SQL निष्पादित करना चाहता हूं .... लेकिन, फिर भी, तर्क मुझे यह भी बताता है कि 2 निष्पादित करना एक बुरा विचार है SQL स्टेटमेंट हर बार जब मुझे एजेंट या लीड की आवश्यकता होती है (क्योंकि प्रत्येक में से हजारों हो सकते हैं)।

मैंने उदाहरणों की खोज करने की कोशिश की है कि इसे आम तौर पर सफलता के साथ कैसे संभाला जाता है ... शायद मैं सिर्फ गलत चीज़ खोज रहा हूं?

उत्तर

7

आप मूल रूप से (जिनमें से एक मैं तुरंत खत्म करने देंगे) इस समस्या के लिए तीन तरीके हैं:

  1. एक वर्ग प्रति तालिका (यह एक मैं खत्म करने जाएगा);
  2. वैकल्पिक कॉलम के साथ एक रिकॉर्ड प्रकार; और
  3. आपके द्वारा शामिल किए जाने वाले प्रकार के आधार पर एक बाल तालिका के साथ एक रिकॉर्ड प्रकार।

सादगी के लिए मैं आम तौर पर अनुशंसा करता हूं (2)। तो एक बार जब आपकी टेबल हो:

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY, 
    type VARCHAR(10), 
    name VARCHAR(100) 
); 

जहां प्रकार 'एजेंट' या 'लीड' (उदाहरण के लिए) हो सकता है। वैकल्पिक रूप से आप एक वर्ण प्रकार कोड का उपयोग कर सकते हैं। फिर आप ऑब्जेक्ट मॉडल के साथ रिक्त स्थान भरना शुरू कर सकते हैं:

  • आपके पास उपयोगकर्ता अभिभावक वर्ग है;
  • आपके दो बच्चे वर्ग हैं: लीड और एजेंट;
  • उन बच्चों के पास एक निश्चित प्रकार है।

और यह आसानी से जगह में गिरना चाहिए।

एक कथन में लोड करने के तरीके के रूप में, मैं किसी प्रकार का कारखाना उपयोग करूंगा। इन 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]'"); 
    } 
} 

, आप कारखाने पद्धति पर कहते हैं, एक स्थिर विधि, उपयोगकर्ता वर्ग है और/या एक इस्तेमाल कर सकते हैं कक्षाओं के प्रकार के लिए लुकअप टेबल।

शायद क्वेरी परिणाम संसाधन के साथ कक्षाओं को प्रदूषित करना सख्त ओओ भावना में एक संदिग्ध डिज़ाइन है, लेकिन यह आसान है और यह काम करता है।

+0

मुझे वास्तव में यह विचार पसंद है, मुझे लगता है। लेकिन जो चीज मुझ पर सबसे ज्यादा है, वह है कि सभी डेटा लोड करने के लिए एसक्यूएल को निष्पादित करना है ... मैं इसे उपयोगकर्ता वर्ग में नहीं डाल सकता क्योंकि इस प्रकार के आधार पर, मुझे अलग-अलग एसक्यूएल की आवश्यकता होगी। मैं इसे सभी एजेंट और लीड क्लास में नहीं रखना चाहता क्योंकि बहुत से कोड समान होंगे और मैं प्रतिलिपि और पेस्ट से बचना चाहता हूं ... आदर्श रूप से, मैं चाहता हूं कि उपयोगकर्ता वर्ग लोड करने में सक्षम हो सामान्य जानकारी और एजेंट/लीड कक्षाओं को अनूठी जानकारी लोड करने के लिए ...... लेकिन फिर जब मैं एजेंट या लीड को तुरंत चालू करता हूं, तो मैं 2 एसक्यूएल स्टेटमेंट निष्पादित कर रहा हूं, जो अवांछनीय है ..... – SpaDusA

+0

आप इसे कर सकते हैं 1 एसक्यूएल कथन में। हालांकि मुझे बताएं, आप किसी विशेष उपयोगकर्ता को लोड करने के लिए क्या उपयोग कर रहे हैं? आप क्या पास करते हैं एक आईडी? कुछ और? – cletus

+0

मेरे पास 2 लोड फ़ंक्शन हैं: loadAll और loadById। प्रत्येक लीड/एजेंट का पहला नाम, अंतिम नाम, उपयोगकर्ता नाम, पासवर्ड, 2 फोन नंबर, ईमेल पता होता है। एक लीड में रुचि का क्षेत्र है और 'आपने हमारे बारे में कैसे सुना है'। एक एजेंट के पास कवरेज क्षेत्र होता है, और वे कौन सी भाषा बोलते हैं। – SpaDusA

0

क्या आपके पास कभी ऐसा उपयोगकर्ता होगा जो लीड या एजेंट नहीं है? क्या उस वर्ग को वास्तव में डेटाबेस से डेटा खींचने की ज़रूरत है?

यदि ऐसा होता है, तो SQL क्वेरी को उस फ़ंक्शन में क्यों न खींचें जिसे आप बच्चे वर्ग बनाते समय ओवरराइड कर सकते हैं।

+0

यह वास्तव में टीम के अन्य लोगों की सिफारिश है। एकमात्र कारण यह है कि मैं एसक्यूएल को एक ऐसे फ़ंक्शन में नहीं रखना चाहता था जिसे मैं ओवरराइड कर सकता हूं क्योंकि एसक्यूएल में से अधिकांश 3 वर्गों में समान है; मैं कार्यों को कॉपी और पेस्ट नहीं करना चाहता था ... मैं एसक्यूएल का अधिग्रहण करना चाहता हूं, इसलिए बोलने के लिए ..... क्या यह बिल्कुल स्पष्ट है? – SpaDusA

0

क्या आप एसक्यूएल के कंकाल को वारिस नहीं कर सकते हैं, फिर प्रत्येक उप-वर्ग में एक फ़ंक्शन का उपयोग अपनी आवश्यकताओं के आधार पर क्वेरी को पूरा करने के लिए करते हैं?

एक बहुत बुनियादी उदाहरण का उपयोग:

<?php 
//our query which could be defined in superclass 
$query = "SELECT :field FROM :table WHERE :condition"; 

//in our subclass 
$field = "user, password, email"; 
$table = "agent"; 
$condition = "name = 'jim'"; 

$dbh->prepare($query); 
$sth->bindParam(':field', $field); 
$sth->bindParam....;//etc 

$sth->execute(); 
?> 

तुम मेरे उदाहरण देख सकते हैं अद्भुत नहीं है, लेकिन आप को देखने के लिए कि मैं क्या पर हो रही है की अनुमति चाहिए। यदि आपकी क्वेरी उप-वर्गों के बीच बहुत समान है तो मुझे लगता है कि मेरा सुझाव काम कर सकता है।

जाहिर है कि इसे कुछ tweaking की आवश्यकता होगी, लेकिन शायद यह दृष्टिकोण मैं ले जाएगा।