【 PHP 】PHP8に入門してみた 208日目 PHPの基本 ( オブジェクト指向 トレイトの注意点)

2023年3月17日

PHP8技術者認定初級試験 が始まるようなので 試験に向けて (できるだけ)勉強しようと思います! 使用する書籍は独習PHP 第4版(山田 祥寛)|翔泳社の本 (shoeisha.co.jp) となります。

オブジェクト指向

トレイトで注意すべきこと

トレイトを使う際に注意が必要なのは、トレイトで定義されたメソッドやプロパティの名前が、既にクラスに存在する名前と競合する場合です。
この場合、名前の競合により、意図しない動作をすることがあります。

この問題を回避するために、以下のような注意点があります。

  1. 名前競合を避けるために、トレイトで定義するメソッドやプロパティの名前には、一意な接頭辞を付ける
  2. もし、名前競合が発生した場合は、クラス側でoverrideする必要があります。
    overrideする場合には、正しいメソッドやプロパティを呼び出せるようにするために、クラスで使用するトレイトの中で同名のメソッドやプロパティを削除する必要があるそうです😑
    これでクラスで定義された同名のメソッドやプロパティが使用されるようになります。
  3. 名前競合を回避するために、トレイトで定義されたメソッドやプロパティの名前には、トレイト名を含めることもできます。
    この場合、トレイト名と共にアンダースコアで区切ることが一般的です。
    例えば、MyTraitクラスで定義されたメソッドfoo()を、クラスで使用する際には、MyClassの中でMyTrait_foo()として使用することができます。

    <?php
      trait MyTrait {
        public function MyTrait_foo() {
          echo 'This is MyTrait_foo() method.';
        }
      }
    
      class MyClass {
        use MyTrait;
      }
    
      $obj = new MyClass();
      $obj->MyTrait_foo(); // "This is MyTrait_foo() method."
    ?>
    

 

他にもinsteadOfasを使用して回避することもできるそうです。

  1. “insteadOf" を使った名前の競合回避
    例えば、トレイト内で定義されたメソッドと、クラス内で定義された同名のメソッドがある場合、
    クラスで以下のように “insteadOf" を使用して名前の競合を回避することができます。

    <!DOCTYPE html>
    
    <html>
    
    
    <head>
        <meta charset="UTF-8" />
        <title>こんにちは!</title>
        <!-- Bootstrapを有効化 -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" />
    </head>
    
    <body>
        <?php
        trait MyTrait
        {
            public function foo()
            {
                echo 'This is MyTrait foo() method.';
            }
        }
    
        class MyClass
        {
            use MyTrait {
                foo insteadOf MyClass;
            }
    
            public function foo()
            {
                echo 'This is MyClass foo() method.';
            }
        }
    
        $obj = new MyClass();
        $obj->foo(); // "This is MyClass foo() method." と出力.
        ?>
    
    </body>
    
    </html>
  2. “as" を使った名前の競合回避
    <!DOCTYPE html>
    
    <html>
    
    
    <head>
        <meta charset="UTF-8" />
        <title>こんにちは!</title>
        <!-- Bootstrapを有効化 -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" />
    </head>
    
    <body>
        <?php
        trait MyTrait
        {
            public function foo()
            {
                echo 'This is MyTrait foo() method.';
            }
        }
    
        class MyClass
        {
            use MyTrait {
                foo as MyTrait_foo;
            }
    
            public function foo()
            {
                echo 'This is MyClass foo() method.';
            }
        }
    
        $obj = new MyClass();
        $obj->foo(); // "This is MyClass foo() method." と出力される
        $obj->MyTrait_foo(); // "This is MyTrait foo() method." と出力される
        ?>
    
    
    </body>
    
    </html>

メモ

うまく使わないといけませんね。

PHPPHP

Posted by raika@blog