2012-10-13 10 views
5

मैं ओओपी के लिए बहुत शुरुआत कर रहा हूं और अब मैं एफ़टीपी सर्वर से कनेक्ट करने के लिए कुछ PHP वर्ग लिखने की कोशिश कर रहा हूं।PHP-OOP दो कक्षाओं का विस्तार?

class ftpConnect { 
    private $server; 
    private $user; 
    private $password; 

    private $connection_id; 
    private $connection_correct = false; 

    public function __construct($server, $user = "anonymous", $password = "[email protected]") { 

    $this->server = $server; 
    $this->user  = $user; 
    $this->password = $password; 

    $this->connection_id  = ftp_connect($this->server); 
    $this->connection_correct = ftp_login($this->connection_id, $this->user, $this->password); 

    if ((!$this->connection_id) || (!$this->connection_correct)){ 
     echo "Error! Couldn't connect to $this->server"; 
     var_dump($this->connection_id); 
     var_dump($this->connection_correct); 
     return false; 
    } else { 
     echo "Successfully connected to $this->server, user: $this->user"; 
     $this->connection_correct = true; 
     return true; 
    } 
    } 
} 

मुझे लगता है कि इस समय कक्षा का वह शरीर महत्वहीन नहीं है।

मुख्य मुद्दा यह है कि मैं OOP विचार को समझने के साथ कुछ समस्या है।

मैं, ईमेल भेजने हर बार जोड़ने के लिए जब कोड चलता है चाहता था। मैं PHPMailer Class डाउनलोड किया है और इसके साथ मेरी कक्षा विस्तार किया है:

class ftpConnect extends PHPMailer {...} 

मैं कुछ चर और तरीकों को शामिल किया है और सब कुछ के रूप में है कि बात करने के लिए उम्मीद काम करता है।

मैंने सोचा: क्यों डेटाबेस में सबकुछ संग्रहित नहीं करना है। हर बार उपयोगकर्ता कोड से ऊपर चलाता है, उचित जानकारी डेटाबेस में संग्रहीत की जानी चाहिए।

मैं अपने ftpConnect class और जोड़ने डेटाबेस निर्माता से कनेक्ट कर रहा है, और अद्यतन करने तालिकाओं के लिए कुछ अन्य विधियों को संपादित कर सकते हैं। लेकिन डाटाबेस कनेक्टिंग और भविष्य में अन्य वर्गों द्वारा उन सभी चीजों का उपयोग किया जा सकता है, इसलिए इसे निश्चित रूप से अलग वर्ग में लागू किया जाना चाहिए। लेकिन मेरा "मुख्य" ftpConnect class पहले से ही एक वर्ग बढ़ाता है और एक और भी नहीं बढ़ा सकता है।

मुझे नहीं पता कि मैं इस समस्या को कैसे हल कर सकता हूं। शायद मेरा ftpConnect class जटिल है और मुझे इसे किसी भी तरह से छोटे वर्गों में विभाजित करना चाहिए? किसी भी मदद की बहुत सराहना की है।

+6

आप बना रहे हैं क्या एक ** भगवान वस्तु **, जो एक वस्तु जो एक बड़ी हिस्सा (या पूरी) आवेदन के लिए जिम्मेदार है कहा जाता है कुछ ऐसी दिखाई देगी। यह अच्छा नहीं है। * प्रत्येक वस्तु की एक जिम्मेदारी होनी चाहिए, और यह * है। मेल करना चाहते हैं? इसके लिए एक अलग वस्तु है। डेटाबेस में सहेजना चाहते हैं? इसके लिए एक अलग वस्तु है। आप रचनाकारों या विधियों के माध्यम से एक दूसरे के संदर्भ पारित करके उन्हें जोड़ सकते हैं। इसे ** निर्भरता इंजेक्शन ** कहा जाता है। इसे देखो। –

+0

स्वतंत्र विशेष वस्तुएं ठीक हैं, जैसे कि हम कॉलेज के प्रोफेसर * सभी * कॉलेज विषयों को पढ़ाने की अपेक्षा नहीं करते हैं। – wallyk

उत्तर

7

शुरुआत के लिए मुझे लगता है कि आपके पास अपनी कक्षा में एक डिज़ाइन दोष है। आपका कन्स्ट्रक्टर काम कर रहा है। यह उचित नहीं है कि एक निर्माता को उचित ओओपी में क्या करना चाहिए। आपके कन्स्ट्रक्टर को केवल गुण सेट करना चाहिए और आपके पास connect() एक अलग विधि होनी चाहिए।

दूसरा ftpConnect कभी PHPMailer का विस्तार कभी नहीं करना चाहिए। वे दो पूरी तरह से अलग चीजें हैं। Liskov substitution principle के बारे में पढ़ें यह SOLID principles का हिस्सा है।

अपनी कक्षा एक डेटाबेस के साथ कुछ करने की जरूरत है या मेल आप उन्हें विस्तार करने के बजाय अपने वर्ग में ऐसे मामलों इंजेक्षन करने की जरूरत है भेजने के लिए की जरूरत है। इसे dependency injection कहा जाता है और इससे बाद में यूनिट परीक्षण करना आसान हो जाएगा, क्योंकि आप आसानी से नकली मेलर क्लास या नकली डेटाबेस क्लास का उपयोग कर सकते हैं।

आप मेल भेजने के लिए चाहते हैं, डेटाबेस का उपयोग किया है और FTP का उपयोग आप कम से कम 3 अलग (अलग) वर्गों की जरूरत है (शायद और भी अधिक db आदि के लिए कुछ मानचित्रण करने के लिए) होगा। असल में प्रत्येक वर्ग में एक जिम्मेदारी और केवल एक होना चाहिए। इसे single responsibility principle कहा जाता है।

कुछ सामान्य संदर्भ के लिए देखें:

0

यह शायद विरासत से अधिक रचना का सवाल देखें इस Prefer composition over inheritance? बस अपने वर्ग के भीतर मेलर वस्तु का उपयोग करें और एक ही उनमें से किसी का विस्तार अपनी कक्षा डीबी के बजाय के लिए चला जाता है।

class my_class 
{ 
    private $mailer; 

    public function __constructor() 
    { 
     $this->mailer = new Mailer(); 
    } 
} 
+0

यह एक अच्छी शुरुआत है, लेकिन @PeeHaa द्वारा सुझाए गए निर्भरता इंजेक्शन का उपयोग करना शायद एक बेहतर विचार है। – igorw

0

डेटाबेस भंडारण भाग के लिए, आप एक अलग वर्ग है, जो अपने डेटाबेस के लिए एक कनेक्शन है बना सकते हैं। आप इस कक्षा के उदाहरण को अपने ftpConnect कक्षा में इसके निर्माता के माध्यम से पास कर सकते हैं। अपने fptConnect को एक ऐसी संपत्ति दें जहां आप इस नई डेटाबेस ऑब्जेक्ट को स्टोर कर सकें, इस तरह आप इस ऑब्जेक्ट को अपने पूरे ftpConnect कक्षा में एक्सेस कर सकते हैं।

आपका ftpConnect वर्ग वर्तमान में एक निर्माता है जो या तो वापस आ जाएगी true या false, न दें निर्माता कोई मूल्य वापस, क्योंकि यह ftpConnect वर्ग का एक उदाहरण है जो आप एक चर के अंदर स्टोर करने के लिए की आवश्यकता होगी वापस जाने के लिए की जरूरत है wil है । इसलिए आप एक अलग विधि में वास्तविक कनेक्शन बना सकते हैं। तो आपकी कक्षा इस तरह कुछ दिख सकती है।

class FtpConnect { 
    private $server; 
    private $user    = "anonymous"; 
    private $password   = "[email protected]"; 
    private $connection_id; 
    private $connection_correct = false; 

    //this will take care of the storage 
    private $database_handler; 

    public function __construct($server, $user, $password, $database_handler) { 
     $this->server = $server; 
     $this->user  = $user; 
     $this->password = $password; 
     $this->database_handler = $database_handler; 

     //store the appropriate data, this will be done everything a new instance is created 
     $this->database_handler->store_data($data_to_store); 
    } 

    public function connect() { 

     //data to store, everytime a connection is made 
     $this->database_handler->store_data($data_to_store); 

     $this->connection_id  = ftp_connect($this->server); 
     $this->connection_correct = ftp_login($this->connection_id, $this->user, $this-  >password); 

     if ((!$this->connection_id) || (!$this->connection_correct)){ 
      echo "Error! Couldn't connect to $this->server"; 
      var_dump($this->connection_id); 
      var_dump($this->connection_correct); 
      return false; 
     } else { 
      echo "Successfully connected to $this->server, user: $this->user"; 
      $this->connection_correct = true; 
      return true; 
     } 
    } 
} 

यह करने के लिए यह एक संभावित तरीका है, शायद अधिक सुंदर समाधान हो सकता है। मेलिंग के तरीके को उसी अवधारणा का उपयोग करके महसूस किया जा सकता है।

यह बाहर से इस

$ftp = new FptConnect('server', 'user', 'password', new DbHandler('server', 'user', 'password', 'host')); 

$ftp->connect(); 
संबंधित मुद्दे