2017-05-07 11 views
6

मैं PHP 7.1.0 का उपयोग करता हूं।क्यों PHP नामों में विधि नामकरण काम नहीं करता है?

मान लें कि हम एक विशेषता है, हम इसे एक वर्ग के अंदर का उपयोग करें और आयातित विधि का नाम बदलने:

trait T 
{ 
    public function A() { 
     echo "."; 
    } 
} 

class C 
{ 
    use T { 
     A as B; 
    } 
} 

$c = new C(); 
$c->B(); 
$c->A(); // Why does it work? 

क्यों पीएचपी अभी भी मुझे (इस मामले में A) पुराना तरीका नाम का उपयोग करने की अनुमति है?

यह वास्तव में एक दर्द है, क्योंकि अधिक जटिल उदाहरण में आप विधि नाम पर भरोसा नहीं कर सकते हैं - और इस प्रकार आप अप्रत्याशित रूप से "असंगत घोषणाओं" त्रुटि प्राप्त कर सकते हैं:

class BaseSrc 
{ 
} 

trait BaseTrait 
{ 
    public function init(BaseSrc $baseSrc) 
    { 
     echo "Init Base"; 
    } 
} 

class Base 
{ 
    use BaseTrait { 
     BaseTrait::init as initBase; 
    } 
} 

$base = new Base(); 
$base->initBase(new BaseSrc()); 
$base->init(new BaseSrc()); // WHY DOES IT WORK????? 

class MainSrc extends BaseSrc 
{ 
} 

trait MainTrait 
{ 
    use BaseTrait { 
     BaseTrait::init as initBase; 
    } 

    public function init(MainSrc $mainSrc) 
    { 
     $this->initBase($mainSrc); 
     echo "Init Main"; 
    } 
} 

// Warning: Declaration of MainTrait::init(MainSrc $mainSrc) should be compatible with Base::init(BaseSrc $baseSrc) 
class Main extends Base 
{ 
    use MainTrait; 
} 

मुझे लगता है, इस कोड को काम करना चाहिए। जब से मैं Base कक्षा में initBase() में init() नाम दिया और जब MainTrait अंदर BaseTrait का उपयोग कर एक ही नाम था, मैं उम्मीद है कि इस विधि (BaseTrait::init()) MainTrait::init() के साथ संघर्ष नहीं होगा। वास्तव में, PHP कहते हैं कि मेरे पास असंगत घोषणाएं हैं। इसके पीछे कारण यह है कि init as initBase नामांकन नहीं करता है - विधि init अभी भी मेरे Base कक्षा में है!

क्या बेसट्रेट :: init() को बहुत शुरुआत से बेसट्रेट :: initBase() जैसे कुछ में नामित किए बिना इस समस्या को हल करने का कोई तरीका है (न केवल use कथन में)?

क्या मुझे इसे एक PHP बग के रूप में माना जाना चाहिए और इसकी रिपोर्ट करना चाहिए? क्या इस व्यवहार के पीछे कुछ भी उचित है?

+1

क्या php.net लिखता है: 'Aliased_Talker एक ** ** अतिरिक्त **' उपनाम बात 'के तहत बी के बड़े टॉक कार्यान्वयन का उपयोग करने में सक्षम होने के लिए ऑपरेटर के रूप में उपयोग करता है। - http://php.net/manual /en/language.oop5.traits.php। तो 'as' उपनाम जोड़ता है लेकिन विधि को प्रतिस्थापित नहीं करता है। और फिर: 'ऑपरेटर के रूप में एक विधि को उपनाम जोड़ने के लिए इस्तेमाल किया जा सकता है। ध्यान दें क्योंकि ऑपरेटर विधि का नाम नहीं बदलता है और यह किसी भी अन्य विधि को प्रभावित नहीं करता है। ' – splash58

+0

@ splash58 ठीक है, धन्यवाद। मैं देखता हूं: "जैसा" नामकरण नहीं कर रहा है, यह सिर्फ "अलियासिंग" है (ईमानदारी से, मैंने इस पृष्ठ को विशेषताओं के बारे में पढ़ने के दौरान इस नोट का उल्लेख नहीं किया है)। क्या इसके पीछे कोई कारण है? मेरा मतलब है, नाम बदलने के बजाए एलियासिंग के किसी भी फायदे? मेरे दृष्टिकोण से, यह बहुत असुविधाजनक है। – Dm9

+0

मुझे लगता है कि 'इसके बजाय' जो आप चाहते हैं उसे बनाएं। क्या मै गलत हु? मुझे पता नहीं है कि गहराई – splash58

उत्तर

0

टिप्पणियों में और पूर्णता के अनुसार उल्लेख किया गया है; PHP manual section on Traits से:

The Aliased_Talker makes use of the as operator to be able to use B's bigTalk implementation under an additional alias talk.

और फिर:

The as operator can be used to add an alias to one of the methods. Note the as operator does not rename the method and it does not affect any other method either.

तो as एक उपनाम कहते हैं, लेकिन बदलने के लिए या किसी भी तरह से मूल विधि को प्रभावित नहीं करता। यह अपेक्षित व्यवहार है।

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