2015-10-07 5 views
6

मैं यह पता लगाने की कोशिश कर रहा हूं कि फ्लाई पर बड़ी संख्या में PHP वर्ग फ़ंक्शन कैसे आयात करें। उदाहरण के लिए ...फ्लाई पर PHP वर्ग फ़ंक्शन को फिर से परिभाषित करना?

class Entity 
{ 
    public function __construct($type) 
    { 
    require_once $type."_functions.php" 
    } 

    // ... 

} 

$person = new Entity("human"); 
$person->sayhi(); 
$cow = new Entity("cow"); 
$cow->sayhi(); 

human_functions.php:

class Entity redefines Entity 
    { 
    public function sayhi() 
     { 
     echo "Hello world!"; 
     } 
    } 

cow_functions.php:

class Entity redefines Entity 
    { 
    public function sayhi() 
     { 
     echo "Moo!"; 
     } 
    } 

मैं classkit_method_redefine() और runkit_method_redefine() की तरह कुछ संभावनाएं (जो "प्रायोगिक" कर रहे हैं पाया है , और वे वर्तमान में चल रहे वर्ग को वैसे भी संशोधित नहीं कर सकते हैं)। मैं फिलहाल PHP 5.3.3 पर हूं, इसलिए मैं Traits का उपयोग नहीं कर सकता (सुनिश्चित नहीं है कि वही है जो मैं वैसे भी ढूंढ रहा हूं)।

// Example 2: 
class OtherEntity { /* Code Here */ } 
class Entity 
    { 
    public function __construct($type) 
     { 
     global $foo; 
     unset($foo); 
     $foo = new OtherEntity(); 
     } 
    } 

$foo = new Entity(); 

, यह एक बहुत hacky विधि की तरह लगता है लेकिन: मैं सफलता इस तरह हैंडलर चर को पुनर्परिभाषित किया था है। सबसे महत्वपूर्ण बात यह है कि, यदि प्रत्येक वर्ग $foo के उदाहरण का नाम नहीं है, तो यह काम नहीं करेगा। क्या मैं क्या करने की कोशिश कर रहा हूं उसके लिए कोई कामकाज है?

नोट: मुझे पता है कि मैं एक वर्ग का विस्तार कर सकते है, लेकिन मेरे मामले में जब इकाई वर्ग शुरू किया जाता है, वहाँ कोई सुरक्षित तरीका अग्रिम क्या यह के साथ शुरू करने की आवश्यकता होगी उपवर्ग में पता करने के लिए है। शायद एक तरीका है जिसे मैं लिख सकता हूं, जैसे:

public function changeClass 
    { 
    this->class = OtherEntity; 
    } 

आपकी मदद के लिए धन्यवाद!

+2

आपकी वास्तविक समस्या का निश्चित समाधान है। आपका पहला उदाहरण [फैक्ट्री पैटर्न] (http://www.tutorialspoint.com/design_pattern/factory_pattern.htm) का सुझाव देता है, लेकिन मुझे यकीन नहीं है कि आप वास्तव में क्या हासिल करना चाहते हैं। – VolkerK

+2

हाँ आपने कुछ डिज़ाइन विकल्पों को बनाया है जिन्हें आपको पुनर्विचार करने की आवश्यकता है। –

+0

एक वास्तविक php फ़ंक्शन 'redefine' है। मेरा मानना ​​है कि आप 'विस्तार' की तलाश में हैं – CodeGodie

उत्तर

5

यहां एक संभावित समाधान का विचार है जिसे आप आजमा सकते हैं। Cow और Human कक्षाएं Entity कक्षा का विस्तार करें। हालांकि, Entity कक्षा मूल्य सुरक्षित होने पर आधारित वस्तुओं को तत्काल करने के लिए factory का उपयोग करेगी। के और अधिक विस्तार में इस पर नजर डालते हैं:

/* 
* Class Entity should not be able to be instantiated. 
* It should contain a factory to instantiate the 
* appropriate entity and an abstract function declaring 
* the method that each entity will need to implement. 
*/ 
abstract class Entity { 

    public static function factory($type) { 
     return (is_subclass_of($type, "Entity")) ? new $type() : FALSE; 
    } 

    abstract public function sayHi(); 

} 

/* 
* Human class extends Entity and implements the 
* abstract method from Entity. 
*/ 
class Human extends Entity { 

    public function sayHi() { 
     echo "Hello World!"; 
    } 

} 

/* 
* Cow class extends Entity and implements the 
* abstract method from Entity. 
*/ 
class Cow extends Entity { 

    public function sayHi() { 
     echo "Moo!"; 
    } 

} 

अब इस विधि का उपयोग करने के लिए, कारखाने विधि कॉल और अगर सब कुछ अच्छी तरह से काम करता है, यह उचित वर्ग जो Entity का विस्तार होगा दृष्टांत होगा।

$person = Entity::factory("Human"); 
$person->sayHi(); 

$cow = Entity::factory("Cow"); 
$cow->sayHi(); 

का उपयोग करना, is_subclass_of() आप सुरक्षित है क्योंकि अगर मूल्य में पारित एक वर्ग है कि Entity फैली नहीं है रहेंगे, आपको FALSE के एक मूल्य वापस आ जाएंगे।

यदि आप उपरोक्त कोड को क्रिया में देखना चाहते हैं, तो ऊपर दिए गए PHP कोड की प्रतिलिपि बनाएँ और इसे phpfiddle.org पर परीक्षण करें।

+0

आप आदमी हैं। धन्यवाद! यही वह है जिसकी तलाश में मैं हूं। आप '' 'sayHi();' '' फ़ंक्शन को मूल रूप से परिभाषित क्यों करते हैं? ऐसा लगता है कि यह मूल '' 'इकाई 'वर्ग में परिभाषित नहीं है .. – DarthCaniac

+2

@DarthCaniac यह सही है। यह बिल्कुल होगा। 'अमूर्त' कीवर्ड का लाभ किसी भी वर्ग को बल देता है जो उस वर्ग को अपनी कक्षा के भीतर लागू करने के लिए 'सार कार्य' के साथ आधार वर्ग का विस्तार करता है। दूसरे शब्दों में, 'मानव' और 'गाय' दोनों को 'sayHi()' को लागू करना है या php दुभाषिया एक त्रुटि फेंक देगा। यह गारंटी है कि 'इकाई' तक फैली किसी भी कक्षा में वैध 'sayHi()' विधि होगी जो उस वर्ग के लिए कुछ विशिष्ट कर सकती है। – War10ck

+0

@ noc2spam ツ विस्तृत करने के लिए देखभाल? ऐसा मत करो क्या? ... – War10ck

1

एक चीज जो आप कर सकते हैं Human और CowEntity के उप-वर्ग के रूप में बना है। जब आप new Entity("Human") करते हैं, तो आपEntity उदाहरण के अंदर एक नव निर्मित Human ऑब्जेक्ट स्टोर कर सकते हैं।

फिर आप "बाल तत्व" पर विधि कॉल को पुनर्निर्देशित करने के लिए __call का उपयोग कर सकते हैं।

class Entity{ 
    private $child; 

    public function __construct($type){ 
     $this->child = new $type; 
    } 

    public function __call($func, $params=array()){ 
     $method = method_exists($this, $func) 
      ? [$this, $func] : [$this->child, $func]; 
     return call_user_func_array($method, $params); 
    } 
} 

class Human extends Entity{ 
    public function __construct(){} 

    public function sayhi(){ 
     echo "Hello world!"; 
    } 
} 

class Cow extends Entity{ 
    public function __construct(){} 

    public function sayhi(){  
     echo "Moo!"; 
    } 
} 

$person = new Entity("Human"); 
$person->sayhi(); 

$cow = new Entity("Cow"); 
$cow->sayhi(); 

केवल नकारात्मक पक्ष यह है कि $person और $cow दोनों Entity वस्तुओं रहे है।

+1

आगे पढ़ने के लिए: यह [ऑब्जेक्ट संरचना] का एक रूप होगा (https://en.wikipedia.org/wiki/Object_composition)। – VolkerK

+0

इंजेक्शन समाधान, धन्यवाद! – DarthCaniac

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