2012-01-03 16 views
42

मैं ऑब्जेक्ट की विधि के अंदर किसी दिए गए तर्क से कोई संपत्ति कैसे बना सकता हूं?गतिशील रूप से नई संपत्ति कैसे बनाएं

class Foo{ 

    public function createProperty($var_name, $val){ 
    // here how can I create a property named "$var_name" 
    // that takes $val as value? 

    } 

} 

और मैं की तरह संपत्ति उपयोग करने में सक्षम होना चाहता हूँ:

$object = new Foo(); 
$object->createProperty('hello', 'Hiiiiiiiiiiiiiiii'); 

echo $object->hello; 

यह भी है कि मैं संपत्ति सार्वजनिक संरक्षित/निजी बना सकता है/हो सकता है? मुझे पता है कि इस मामले में यह सार्वजनिक किया जाना चाहिए, लेकिन मैं संरक्षित गुण और सामान :)


पाने के लिए कुछ magik तरीकों जोड़ सकते हैं मुझे लगता है कि मैं एक समाधान मिला:

protected $user_properties = array(); 

    public function createProperty($var_name, $val){ 
    $this->user_properties[$var_name] = $val; 

    } 

    public function __get($name){ 
    if(isset($this->user_properties[$name]) 
     return $this->user_properties[$name]; 

    } 

आप करते हैं लगता है कि यह एक अच्छा विचार है?

उत्तर

60

ऐसा करने के दो तरीके हैं।

एक, तो आप सीधे गतिशील संपत्ति बना सकते हैं वर्ग बाहर से:

class Foo{ 

} 

$foo = new Foo(); 
$foo->hello = 'Something'; 

या यदि आप अपने createProperty विधि के माध्यम से संपत्ति बनाने के लिए चाहते हैं:

class Foo{ 
    public function createProperty($name, $value){ 
     $this->{$name} = $value; 
    } 
} 

$foo = new Foo(); 
$foo->createProperty('hello', 'something'); 
+0

धन्यवाद। हालांकि मुझे कक्षा के अंदर इसकी ज़रूरत है। यह समझाने के लिए जटिल है, गुण वास्तव में वे वस्तुएं हैं जो साइट एक्सटेंशन हैं जो साइट व्यवस्थापक सक्षम/अक्षम कर सकते हैं :) लेकिन मैं अपने समाधान का उपयोग करूंगा, मुझे लगता है कि उन्हें एक सरणी के अंदर रखना बेहतर है। – Alex

+3

क्या उन्हें निजी या संरक्षित के रूप में सेट करना संभव है? –

+0

इस तरह की संपत्ति सेट करने से हमें इसे निजी या संरक्षित करने की अनुमति नहीं मिलती क्योंकि यह सार्वजनिक रूप से सेट की जाती है। हालांकि, आप ओओपी जादू विधियों '__get() 'और' __set() 'के साथ काम करने का प्रयास कर सकते हैं। Http://stackoverflow.com/questions/4713680/php-get-and-set-magic-methods – mauris

5

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

__isset(); __unset();

आप बाद में जब इन वस्तु के प्रयोग पर कुछ आम गलतियों को खोजने के लिए नहीं करना चाहते हैं "विशेषता"

यहाँ कुछ उदाहरण हैं:

http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members

एलेक्स टिप्पणी के बाद संपादित:

आप दोनों समाधानों के बीच समय में मतभेदों को देख सकते हैं ($ REPEAT_PLEASE बदलें)

<?php 

$REPEAT_PLEASE=500000; 

class a {} 

$time = time(); 

$a = new a(); 
for($i=0;$i<$REPEAT_PLEASE;$i++) 
{ 
$a->data = 'hi'; 
$a->data = 'bye'.$a->data; 
} 

echo '"NORMAL" TIME: '.(time()-$time)."\n"; 

class b 
{ 
     function __set($name,$value) 
     { 
       $this->d[$name] = $value; 
     } 

     function __get($name) 
     { 
       return $this->d[$name]; 
     } 
} 

$time=time(); 

$a = new b(); 
for($i=0;$i<$REPEAT_PLEASE;$i++) 
{ 
$a->data = 'hi'; 
//echo $a->data; 
$a->data = 'bye'.$a->data; 
} 

echo "TIME OVERLOADING: ".(time()-$time)."\n"; 
+0

बनायेगा, मैं __get/__set/__call की आदी हूं। मैं उस वर्ग का उपयोग करते समय अच्छा एपीआई प्राप्त करने के लिए हर वर्ग में उन्हें व्यावहारिक रूप से उपयोग करता हूं ... अब तक __isset की आवश्यकता नहीं है .. क्या आप ओवरलोडिंग से संबंधित कुछ बेंचमार्क के साथ एक लिंक या कुछ प्रदान कर सकते हैं? – Alex

+0

बुरी खबरों के लिए खेद है लेकिन __call वास्तव में भी धीमा है –

+0

"संपत्ति अधिभार धीमा है" के लिए कुछ संदर्भ/सबूत दिखाएं। – Pacerier

4

उपयोग वाक्य रचना: $ वस्तु -> {$ संपत्ति} जहां $ संपत्ति एक स्ट्रिंग चर और $ वस्तु है यह हो सकता है अगर यह वर्ग या किसी उदाहरण ऑब्जेक्ट के अंदर है

लाइव उदाहरण: http://sandbox.onlinephpfunctions.com/code/108f0ca2bef5cf4af8225d6a6ff11dfd0741757f

class Test{ 
    public function createProperty($propertyName, $propertyValue){ 
     $this->{$propertyName} = $propertyValue; 
    } 
} 

$test = new Test(); 
$test->createProperty('property1', '50'); 
echo $test->property1; 

परिणाम: 50

+0

यह वह उत्तर है जिसे मैं ढूंढ रहा था, मैं पहले से ही नया हूं कि आप केवल उन वस्तुओं में गुणों का संदर्भ दे सकते हैं जो पहले नहीं हैं घोषित किया गया ... $ वस्तु-> उदाहरण = "हैलो"; जब आप संपत्ति को कॉल करना चाहते हैं तो गतिशील रूप से निर्दिष्ट करने के दौरान आप ऑब्जेक्ट को गतिशील रूप से संपत्ति को जोड़ने के बाद और अधिक थे। – andmar8

1

निम्न उदाहरण जो लोग एक पूरे वर्ग घोषित करने के लिए नहीं करना चाहते हैं के लिए है।

$test = (object) []; 

$prop = 'hello'; 

$test->{$prop} = 'Hiiiiiiiiiiiiiiii'; 

echo $test->hello; // prints Hiiiiiiiiiiiiiiii 
संबंधित मुद्दे