बेरी के उत्तर पर विस्तार करने के लिए, कि संरक्षित स्तर तक पहुँच स्थापित करने की अनुमति देता है __get और __set को स्पष्ट रूप से घोषित गुणों (जब कक्षा के बाहर एक्सेस किया जाता है, कम से कम) और गति काफी धीमी होने के साथ उपयोग करने की अनुमति देता है, मैं दूसरे प्रश्न से एक टिप्पणी उद्धृत करूंगा। इस विषय पर और वैसे भी इसका उपयोग करने के लिए एक मामला बनाएं:
मैं मानता हूँ कि __get एक कस्टम गेट फ़ंक्शन (समान कामों) को करने में अधिक धीमा है, यह 0.0124455 __get () के लिए समय है और यह 0.0024445 10000 लूप के बाद कस्टम गेट () के लिए है। - Melsi Nov 23 '12 22:32 सर्वश्रेष्ठ अभ्यास: PHP मैजिक मेथड्स __set और __get
मेल्सी के परीक्षणों के अनुसार, काफी धीमा लगभग 5 गुना धीमा है। यह निश्चित रूप से काफी धीमा है, लेकिन यह भी ध्यान दें कि परीक्षणों से पता चलता है कि आप अभी भी 10,000 बार लूप पुनरावृत्ति के लिए गिनती के समय में इस पद्धति के साथ एक संपत्ति तक पहुंच सकते हैं, लगभग 1/100 सेकंड में। यह वास्तविक रूप से निर्धारित और निर्धारित विधियों की तुलना में काफी धीमा है, और यह एक समझ है, लेकिन चीजों की भव्य योजना में, यहां तक कि 5 गुना धीमी गति वास्तव में धीमी नहीं है।
ऑपरेशन का कंप्यूटिंग समय अभी भी नगण्य है और वास्तविक दुनिया के 99% अनुप्रयोगों में विचार करने लायक नहीं है। वास्तव में केवल तभी बचा जाना चाहिए जब आप वास्तव में एकल अनुरोध में 10,000 से अधिक बार संपत्तियों तक पहुंच बनाने जा रहे हों। यदि वे अपने अनुप्रयोगों को चालू रखने के लिए कुछ और सर्वरों को फेंक नहीं सकते, तो उच्च यातायात साइटें वास्तव में कुछ गलत कर रही हैं। एक उच्च ट्रैफ़िक साइट के पाद लेख पर एक एकल पंक्ति पाठ विज्ञापन जहाँ पहुँच दर एक समस्या बन जाती है वह संभवतः पाठ की उस पंक्ति के साथ 1,000 सर्वरों के फ़ार्म के लिए भुगतान कर सकता है। अंतिम उपयोगकर्ता कभी भी यह कहते हुए अपनी उंगलियों को टैप करने वाला नहीं है कि पेज को लोड करने के लिए इतना लंबा समय क्यों लग रहा है क्योंकि आपके आवेदन की संपत्ति का उपयोग सेकंड का दसवां हिस्सा लेता है।
मैं इसे एक .NET में पृष्ठभूमि से आने वाले डेवलपर के रूप में बोल रहा हूं, लेकिन उपभोक्ता को अदृश्य तरीके और सेट किए गए तरीके .NET के आविष्कार नहीं हैं। वे बस उनके बिना गुण नहीं हैं, और ये जादुई तरीके PHP के डेवलपर की कृपा के गुणों के अपने संस्करण को "गुणों" के लिए बुला रहे हैं। इसके अलावा, PHP के लिए विजुअल स्टूडियो एक्सटेंशन संरक्षित गुणों के साथ इंटेलीजेंस का समर्थन करता है, उस चाल को ध्यान में रखते हुए, मुझे लगता है। मैं इस तरह से जादू __get और __set विधियों का उपयोग करने वाले पर्याप्त डेवलपर्स के साथ सोचूंगा, PHP डेवलपर्स डेवलपर समुदाय को पूरा करने के लिए निष्पादन समय को ट्यून करेंगे।
संपादित करें: सिद्धांत रूप में, संरक्षित गुण ऐसा लगता था कि यह अधिकांश स्थिति में काम करेगा। व्यवहार में, यह पता चलता है कि बहुत बार आप अपने गेटर्स का उपयोग करना चाहते हैं और वर्ग की परिभाषा और विस्तारित कक्षाओं के भीतर गुणों तक पहुँचते समय बस जाते हैं। एक बेहतर समाधान अन्य वर्गों का विस्तार करते समय के लिए एक बेस क्लास और इंटरफ़ेस है, इसलिए आप बेस क्लास से कोड की कुछ पंक्तियों को लागू करने वाली क्लास में कॉपी कर सकते हैं। मैं अपनी परियोजना के आधार वर्ग के साथ थोड़ा अधिक कर रहा हूं, इसलिए मेरे पास अभी प्रदान करने के लिए कोई इंटरफ़ेस नहीं है, लेकिन यहां जादू की संपत्ति के साथ वर्गीय परिभाषा को छीन लिया गया है और गुणों को हटाने और स्थानांतरित करने के लिए प्रतिबिंब का उपयोग करके सेट किया गया है। एक संरक्षित सरणी:
class Component {
protected $properties = array();
public function __get($name) {
$caller = array_shift(debug_backtrace());
$max_access = ReflectionProperty::IS_PUBLIC;
if (is_subclass_of($caller['class'], get_class($this)))
$max_access = ReflectionProperty::IS_PROTECTED;
if ($caller['class'] == get_class($this))
$max_access = ReflectionProperty::IS_PRIVATE;
if (!empty($this->properties[$name])
&& $this->properties[$name]->class == get_class()
&& $this->properties[$name]->access <= $max_access)
switch ($name) {
default:
return $this->properties[$name]->value;
}
}
public function __set($name, $value) {
$caller = array_shift(debug_backtrace());
$max_access = ReflectionProperty::IS_PUBLIC;
if (is_subclass_of($caller['class'], get_class($this)))
$max_access = ReflectionProperty::IS_PROTECTED;
if ($caller['class'] == get_class($this))
$max_access = ReflectionProperty::IS_PRIVATE;
if (!empty($this->properties[$name])
&& $this->properties[$name]->class == get_class()
&& $this->properties[$name]->access <= $max_access)
switch ($name) {
default:
$this->properties[$name]->value = $value;
}
}
function __construct() {
$reflected_class = new ReflectionClass($this);
$properties = array();
foreach ($reflected_class->getProperties() as $property) {
if ($property->isStatic()) { continue; }
$properties[$property->name] = (object)array(
'name' => $property->name, 'value' => $property->value
, 'access' => $property->getModifier(), 'class' => get_class($this));
unset($this->{$property->name}); }
$this->properties = $properties;
}
}
कोड में कोई भी बग होने पर मेरी क्षमा याचना।