Sobes.tech
Middle

Эки trait бирдей аталыштагы ыкмам бар болсо, эмне кылуу керек?

sobes.tech AI

AIден жооп

Модулдуу аталыштардын кагылышуусу болгондо, чечүүнүн бир нече варианты бар:

  1. insteadof префикс оператору: Бул белгилүү бир traitтен методду тандап алууга мүмкүндүк берет, башка traitтен бирдей аталыштагы методду эске албастан.

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA-дан";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB-дан";
        }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitA::doSomething insteadof TraitB; // TraitA-дан методду колдонобуз
        }
    }
    
    $obj = new MyClass();
    $obj->doSomething(); // "TraitA-дан" чыгат
    

    Көптөгөн чыгымдар көрсөтүлүшү мүмкүн:

    <?php
    trait TraitA {
        public function methodA() { echo "A_a"; }
        public function methodB() { echo "A_b"; }
    }
    
    trait TraitB {
        public function methodA() { echo "B_a"; }
        public function methodB() { echo "B_b"; }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitA::methodA insteadof TraitB;
            TraitB::methodB insteadof TraitA;
        }
    }
    
  2. as префикс оператору: Бул конфликт болгон методду кайра аталышын өзгөртүүгө мүмкүндүк берет:

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA-дан";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB-дан";
        }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitB::doSomething as doSomethingFromB; // TraitB-дан методду кайра аталышын өзгөртүп жатабыз
        }
    
        public function callBoth() {
            $this->doSomething(); // TraitA-дан методду чакырат
            $this->doSomethingFromB(); // кайра аталышта турган методду чакырат
        }
    }
    
    $obj = new MyClass();
    $obj->callBoth(); // "TraitA-данTraitB-дан" чыгат
    

    as оператору insteadof менен бирге колдонулушу мүмкүн жана методдун көрүнүшүн өзгөртүүгө мүмкүндүк берет.

    <?php
    trait TraitA {
        private function internalMethod() {
            echo "TraitA-дан жеке метод";
        }
    }
    
    class MyClass {
        use TraitA {
            internalMethod as public externalMethod; // Атын өзгөртүп, коомдук кылдык
        }
    }
    
    $obj = new MyClass();
    $obj->externalMethod(); // "TraitA-дан жеке метод" чыгат
    
  3. Класс ичинде методду так аныктоо: Trait-терди колдонуп жаткан класс ошол эле аталыштагы методду так аныктап койсо, ал метод trait-тердин методдорунан артык болот:

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA-дан";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB-дан";
        }
    }
    
    class MyClass {
        use TraitA, TraitB;
    
        public function doSomething() { // Класс өзүнүн методун аныктайт
            echo "MyClass-дан";
        }
    }
    
    $obj = new MyClass();
    $obj->doSomething(); // "MyClass-дан" чыгат
    

Ачык жана так чечимдерсиз, insteadof же as колдонуу же методду кайра аныктоо аркылуу, PHP ката чыгарат E_STRICT.