मैं __get() उपयोग कर रहा हूँ मेरे गुण के कुछ "डायनामिक" बनाने के लिए अनुकरण करने के लिए __get() (जादू) का उपयोग करना (केवल जब अनुरोध उन्हें प्रारंभ)। ये "नकली" गुण एक निजी सरणी संपत्ति के अंदर संग्रहीत हैं, जिन्हें मैं __get के अंदर देख रहा हूं।केवल पढ़ने के लिए प्रॉपर्टीज़ और आलसी लोडिंग
वैसे भी, आपको लगता है इसके बजाय इनमें proprties से प्रत्येक के लिए तरीकों बनाने के लिए बेहतर विचार है एक स्विच बयान में यह कर के हो?
संपादित करें: स्पीड परीक्षण
मैं, केवल प्रदर्शन को लेकर चिंतित हूं अन्य सामग्री पर @Gordon उल्लेख किया मुझे लगता है कि महत्वपूर्ण नहीं हैं:
- अनावश्यक जटिलता - यह नहीं है वास्तव में मेरे एप्लिकेशन जटिलता
- नाजुक गैर स्पष्ट एपीआई वृद्धि - मैं विशेष रूप से मेरी एपीआई "पृथक" होना चाहते हैं; तो यहाँ पी
परीक्षण है कि मैं बनाया है, जो मुझे लगता है कि प्रदर्शन हिट agument अनुचित है कर रहे हैं: प्रलेखन दूसरों है कि यह कैसे उपयोग करने के लिए बताना चाहिए 50.000 कॉल (पीएचपी 5.3 पर के लिए
परिणाम .9):
(t1 = स्विच, t2 = गेटर, t3 = आगे गेटर कॉल के साथ जादू)
नहींयकीन है कि क्या "सह" बात मतलब के साथ जादू टी 3 पर। यह नहीं कर सकते संचयी समय हो क्योंकि t2 2K तो होना चाहिए ...
कोड:
class B{}
class A{
protected
$props = array(
'test_obj' => false,
);
// magic
function __get($name){
if(isset($this->props[$name])){
switch($name){
case 'test_obj':
if(!($this->props[$name] instanceof B))
$this->props[$name] = new B;
break;
}
return $this->props[$name];
}
trigger_error('property doesnt exist');
}
// standard getter
public function getTestObj(){
if(!($this->props['test_obj'] instanceof B))
$this->props['test_obj'] = new B;
return $this->props['test_obj'];
}
}
class AA extends A{
// magic
function __get($name){
$getter = "get".str_replace('_', '', $name); // give me a break, its just a test :P
if(method_exists($this, $getter))
return $this->$getter();
trigger_error('property doesnt exist');
}
}
function t1(){
$obj = new A;
for($i=1;$i<50000;$i++){
$a = $obj->test_obj;
}
echo 'done.';
}
function t2(){
$obj = new A;
for($i=1;$i<50000;$i++){
$a = $obj->getTestObj();
}
echo 'done.';
}
function t3(){
$obj = new AA;
for($i=1;$i<50000;$i++){
$a = $obj->test_obj;
}
echo 'done.';
}
t1();
t2();
t3();
पुनश्च: मैं क्यों __get() मानक गेटर तरीकों से अधिक उपयोग करने के लिए करना चाहते हैं? एपी सौंदर्य एकमात्र कारण है; क्योंकि मैं किसी भी असली नुकसान नहीं दिख रहा है, मुझे लगता है यह इसके लायक है: पी
संपादित करें: अधिक गति परीक्षण
इस बार मैं microtime इस्तेमाल किया कुछ औसत को मापने के लिए:
पीएचपी 5.2। 4 और 5.3.0 (इसी तरह के परिणाम):
t1 - 0.12s
t2 - 0.08s
t3 - 0.24s
पीएचपी 5.3.9, xdebug सक्रिय के साथ इस कारण है कि यह इतनी धीमी गति से है:
t1 - 1.34s
t2 - 1.26s
t3- 5.06s
पीएचपी xdebug साथ 5.3.9 अक्षम:
t1 - 0.30
t2 - 0.25
t3 - 0.86
एक अन्य विधि:
// magic
function __get($name){
$getter = "get".str_replace('_', '', $name);
if(method_exists($this, $getter)){
$this->$name = $this->$getter(); // <-- create it
return $this->$name;
}
trigger_error('property doesnt exist');
}
का अनुरोध नाम के साथ एक सार्वजनिक संपत्ति पहले __get कॉल के बाद गतिशील बनाया जाएगा। यह गति मुद्दों को हल करती है - पीएचपी 5.3 में 0.1s हो रही है (यह 12 गुना तेजी से तो मानक गेटर है), और तानाना मुद्दा गॉर्डन द्वारा उठाए गए। आप बच्चे वर्ग में गेटटर को ओवरराइड कर सकते हैं।
नुकसान यह है कि संपत्ति बन जाता है है लिखने योग्य :(
इन परीक्षणों पर, "सह" कार्य के समय की मात्रा है, जिसमें से किसी भी कार्य के समय शामिल है (मूल रूप से यह वास्तविक समय की मात्रा है जब फ़ंक्शन तब तक निष्पादित होने तक कार्य शुरू होता है)। यह "स्वयं" समय से अलग है, जो अन्य कार्यों को बुलाए जाने पर टाइमर को प्रभावी रूप से "रोक देता है"। इस मामले में, टी 3 के लिए "सह" माइनस "सेल्फ" इस काम में कितना समय व्यतीत किया गया है -> $ गेटर() कॉल, और "स्वयं" यह है कि इसमें अन्य सामान करने में कितना समय लगेगा __get() फ़ंक्शन। –