2009-02-10 12 views
12

मैं PHPPHP नेस्टेड क्लास या नेस्टेड विधियों को कैसे करें?

$myDBClass->users()->limit(5);//output you limited users to 5 
$myDBClass->comments()->limit(3);//output you limited comments to 3 

में यह कैसे कर सकते मैं क्या मतलब नेस्टेड तरीकों या नेस्टेड वर्ग (मैं नहीं जानता कि!) इसलिए जब मैं उन के एक बच्चे के रूप में सीमा विधि कॉल यह पता चल जाएगा कि है मैं इसे "उपयोगकर्ताओं" विधि से कॉल कर रहा हूं- या कक्षा- और जब मैं सीमा विधि-कक्षा को कॉल करता हूं! - टिप्पणियों से यह भी जानता है।

इस बात को करने के लिए PHP कक्षा के लिए संभावित संरचना क्या है?


इस प्रश्न के लिए कारण है क्योंकि मैं डेटाबेस के लिए अपने ही वर्ग पर काम कर रहा हूँ तो मैं आसानी से एसक्यूएल कोड उत्पन्न करने के लिए इस

 $DB->comments()->id(" > 3")->limit(10); 

की तरह कुछ का उपयोग कर सकते "टिप्पणी से चयन * जहां आईडी> 3 सीमा 10 " धन्यवाद

+4

Dude यह है ** श्रृंखलन **, घोंसला नहीं। – Pacerier

उत्तर

17

विधियों को वर्णित विधियों के साथ ऑब्जेक्ट्स लौटाएं, और आप जो भी प्राप्त कर रहे हैं उसे प्राप्त करें।

तो, जब तक $DB एक ऐसी वस्तु है जिसमें comments() -method है, वह हिस्सा मान्य है। यदि वह comments() एक ऑब्जेक्ट देता है जिसमें id() -method है, तो वह भाग मान्य भी है। फिर, id() को उस ऑब्जेक्ट को वापस करने की आवश्यकता है जिसमें limit() -method है।

अपने विशेष मामले में, अगर आप इस तरह कुछ करने के लिए चाहते हो सकता है:

class DB { 
    public function comments() { 
    // do preparations that make the object select the "comments"-table... 
    return $this; 
    } 

    public function id($string) { 
    // handle this too... 
    return $this; 
    } 

    public function limit($int) { 
    // also this 
    return $this; 
    } 

    public function execute() { 
    $success = try_to_execute_accumulated_db_commands(); 
    return $success; 
    } 
} 

$DB = new DB(); 

मेरे उदाहरण में, हर विधि (भी यहाँ दर्शाया नहीं), वस्तु ही वापसी होगी ताकि आदेशों एक साथ श्रृंखलित किया जा सकता है । जब डेटाबेस क्वेरी का निर्माण किया जाता है, तो आप वास्तव में execute() का आह्वान करके क्वेरी का मूल्यांकन करते हैं (मेरे मामले में) एक बूलियन लौटाएगा जो डेटाबेस निष्पादन की सफलता का प्रतिनिधित्व करेगा।

उपयोगकर्ता निकोम ने सुझाव दिया कि इसे fluent interface कहा जाता है। मुझे यह स्वीकार करना होगा कि यह मेरे लिए एक नया शब्द है, लेकिन यह शब्द के उपयोग की तुलना में शायद मेरे अधिक ज्ञान को बताता है। ("मैं सिर्फ कोड लिखने, तुम्हें पता है ...")

नोट:$this एक 'जादू' चर कि वर्तमान में सक्रिय वस्तु की ओर इशारा करता है। जैसा कि नाम से पता चलता है, यह सिर्फ विधि के लिए वापसी मूल्य के रूप में खुद को लौटाता है।

+0

महान उदाहरण। मैं बस कुछ ठीक उसी तरह पोस्ट करने वाला था। शायद यह उल्लेख करना चाहें कि इसे एक धाराप्रवाह इंटरफ़ेस कहा जाता है: http://en.wikipedia.org/wiki/Fluent_interface – nickohrn

+0

इसका उपयोग ExtPHP http://nexus.zteo.com/2008/03/04/extphp-an- ExtJS-converterwrapper के लिए php-डेवलपर्स / – Seiti

9

इसके लिए मानक सम्मेलन प्रत्येक विधि कॉल के अंत में $ के उदाहरण को वापस करना है। तो जब कॉलर पर लौट आए तो हम सिर्फ एक और विधि कॉल का संदर्भ दे रहे हैं।

class Foo 
{ 
    public function do_something() 
    { 
    return $this; 
    } 

public function do_something_else() 
{ 
    return $this; 
    } 
} 

$foo->do_something()->do_something_else(); 
0

एक सरल विधि को लागू करने के लिए आप की तरह हो सकता आरंभ करने के लिए:

class db 
{ 
    public function __call($function, $arguments) 
    { 
    switch($function) { 
     // implement table handling here 
     case 'user': 
     //do something 
     return $something; 
     break; 
    } 
    } 
} 

या नहीं, आप जटिल है, लेकिन ठोस या साधारण जाना चाहता हूँ पर निर्भर करता है, लेकिन कम सुविधाजनक आप दो अलग अलग रणनीतियों को लागू कर सकते हैं। सरल रणनीति इसलिए की तरह जा सकते हैं:

class db 
{ 

    protected $operatingTable; 

    public function limit($limitNumber) 
    { 
    return $this->executeQuery("SELECT * FROM ".$this->operatingTable." LIMIT ".$limitNumber); // where executeQuery is a function that runs a query 
    } 

    public function __call($function, $arguments) 
    { 
    switch($function) { 
     // implement table handling here 
     case 'user': 
     $this->operatingTable='user'; // alternately, but less secure: $this->operatingTable=$function; 
     return $this; 
     break; 
    } 
    } 
} 

वैकल्पिक रूप से, लेकिन अधिक शक्तिशाली:

class db 
{ 
    protected $operatingTable; 

    public function limit($limitNumber) 
    { 
    return $this->executeQuery("SELECT * FROM ".$this->operatingTable." LIMIT ".$limitNumber); // where executeQuery is a function that runs a query 
    } 

    public function __call($function, $arguments) 
    { 
    switch($function) { 
     // implement table handling here 
     case 'user': 
     $user = new user($this); // pass in the database to the object, so the table object can have a reference to the db 
     return $user; 
     break; 
    } 
    } 
} 

class baseTableClass 
{ 
    protected $db; // an instance of class db 

    function limit($limitNumber) 
    { 
    $db->execute($aStatementDerivedFromThisClassesInformation); // execute a sql command, based on information about the table in the class 
    } 

} 

class user extends baseTableClass 
{ 
    public function __construct($db) { 
    $this->db = $db; 
    } 
} 

आप अंदाजा हो। या तो ओवरलोड डाटाबेस वस्तु, या एक आधार डाटाबेस वस्तु बनाने, और तालिका वस्तुओं, टेबल वस्तुओं में बुद्धि के बहुत डाल, यह सुनिश्चित करना कि जब बनाया, एक मेज वस्तु भंडार db ऑब्जेक्ट के संदर्भ

संबंधित मुद्दे