Sobes.tech
Middle

Mit tegyünk, ha két trait ugyanazzal a névvel rendelkező metódussal rendelkezik?

sobes.tech MI

Válasz az MI-től

Amikor konfliktus van a metódusnevekben a trait-ek között, több megoldás is létezik:

  1. Az insteadof prefix operátor: Lehetővé teszi, hogy egy adott trait-ből válasszunk ki egy metódust, figyelmen kívül hagyva ugyanazon névvel rendelkező metódust egy másik trait-ből.

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA-ból";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB-ből";
        }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitA::doSomething insteadof TraitB; // A TraitA metódusát használjuk
        }
    }
    
    $obj = new MyClass();
    $obj->doSomething(); // "TraitA-ból" lesz a kimenet
    

    Több kivételt is megadhatunk:

    <?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. Az as prefix operátor: Lehetővé teszi egy konfliktusban lévő metódus átnevezését.

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA-ból";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB-ból";
        }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitB::doSomething as doSomethingFromB; // Átnevezzük a TraitB-ből származó metódust
        }
    
        public function callBoth() {
            $this->doSomething();        // A TraitA-ból származó metódust hívja
            $this->doSomethingFromB(); // A átnevezett metódust hívja
        }
    }
    
    $obj = new MyClass();
    $obj->callBoth(); // "TraitA-bólTraitB-ból" lesz a kimenet
    

    Az as operátor használható az insteadof-val kombinálva, és lehetővé teszi a metódus láthatóságának módosítását.

    <?php
    trait TraitA {
        private function internalMethod() {
            echo "TraitA privát metódusa";
        }
    }
    
    class MyClass {
        use TraitA {
            internalMethod as public externalMethod; // Átnevezzük és nyilvánossá tesszük
        }
    }
    
    $obj = new MyClass();
    $obj->externalMethod(); // "TraitA privát metódusa" lesz a kimenet
    
  3. Kifejezetten a class-ban definiált metódus: Ha a trait-et használó osztály kifejezetten definiál egy ugyanilyen nevű metódust, akkor ez a metódus fog elsőbbséget élvezni a trait-ek metódusai felett.

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA-ból";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB-ből";
        }
    }
    
    class MyClass {
        use TraitA, TraitB;
    
        public function doSomething() { // A class saját metódusát definiálja
            echo "MyClass-ból";
        }
    }
    
    $obj = new MyClass();
    $obj->doSomething(); // "MyClass-ból" lesz a kimenet
    

Névtelenül a insteadof vagy az as használata vagy a metódus felülírása nélkül a PHP hibát fog jelezni E_STRICT kóddal, amikor konfliktusos trait metódusokat tartalmazó osztályt próbálunk használni.