post-image

Traits trong PHP

Tổng quan

Traits trong PHP có thể hiểu như là một class, nó tập hợp một nhóm các phương thức (method) mà chúng ta muốn sử dụng trong các class khác. Cùng tìm hiểu khái niệm này nhé.

Traits là gì ?

Traits có thể hiểu như là một class, nó tập hợp một nhóm các phương thức (method) mà chúng ta muốn sử dụng trong các class khác. Cũng giống như Abstract Class chúng ta không thể khởi tạo một đối tượng mới từ Traits.

Example

Khai báo:

<?php

trait Demo {
  public function demo()
  {
    return 'Demo Traits';
  }
}

Hãy tạo ra một vài class khác để sử dụng Trait mà chúng ta vừa tạo ra.


class Post {
  use Demo;
}

class Comment {
  use Demo;
}

Bạn có thể hình dung rằng, việc sử dụng nó chính là chúng ta viết 1 phương thức để cả 2 class Post và Comment có thể sử dụng được. Sau khi khai báo như trên, để sử dụng được method demo trong nó, chúng ta sử dụng đơn giản như sau:

$post = new Post;
echo $post->demo(); // 'Demo Traits'

$comment = new Comment;
echo $comment->demo(); // 'Demo Traits'

Qua ví dụ trên, chúng ta đã hiểu đôi chút cách sử dụng của Trait. Hãy xem ví dụ sau.

Multiple Traits

Hãy theo dõi đoạn code.

<?php
trait Hello
{
    function sayHello() {
        echo "Hello";
    }
}

trait World
{
    function sayWorld() {
        echo "World";
    }
}

class MyWorld
{
    use Hello, World;
}

$world = new MyWorld();
echo $world->sayHello() . " " . $world->sayWorld(); //Hello World

ở đây chúng ta có 2 Trait, Hello và World. Trait Hello, chỉ có thể in ra “Hello”, còn Trait World in ra “World”. Trong class MyWord chúng ta đã use cả 2 Trait trên, do đó để in ra được đoạn text “Hello World” thì chúng ta chỉ cẩn gọi phương thức bên trong mỗi Trait như trên.

Traits Composed of Traits

PHP 5.4 cho phép chúng ta tạo một Traits mới được cấu tạo từ nhiều Trait khác nhau. Nhờ đó, chúng ta chỉ cần include một Trait thay vì include nhiều Traits như trước đây. Xem ví dụ sau:


<?php
trait HelloWorld
{
    use Hello, World;
}

class MyWorld
{
    use HelloWorld;
}

$world = new MyWorld();
echo $world->sayHello() . " " . $world->sayWorld(); //Hello World

Trong ví dụ bên trên để sử dụng được Traits Hello và Traits World, chúng ta cần use Hello, World. Thay vì làm điều này, chúng ta khai báo một Trait mới với tên HelloWorld. Trong trait này chúng ta gọi đến 2 Trail con là Hello và World đã định nghĩa ở bên trên. Tất nhiên đẻ gọi được phương thức con của chúng, chúng ta vẫn gọi như cũ. ^^

** Ưu tiên theo thứ tự**

Các thứ tự ưu tiên sẽ là:

  • Method của những traits override đươc kế thừa các phương thức của lớp cha.
  • Method được định nghĩa tại class overide.
<?php
trait Hello
{
    function sayHello() {
        return "Hello";
    }

    function sayWorld() {
        return "Trait World";
    }

    function sayHelloWorld() {
        echo $this->sayHello() . " " . $this->sayWorld();
    }

    function sayBaseWorld() {
        echo $this->sayHello() . " " . parent::sayWorld();
    }
}

class Base
{
    function sayWorld(){
        return "Base World";
    }
}

class HelloWorld extends Base
{
    use Hello;
    function sayWorld() {
        return "World";
    }
}

$h =  new HelloWorld();
$h->sayHelloWorld(); // Hello World
$h->sayBaseWorld(); // Hello Base World

Conflict Resolution and Aliasing

Khi chúng ta sử dụng multiple trait, chúng ta khó tránh được những trường hợp như ví dụ sau.

<?php
trait Game
{
    function play() {
        echo "Playing a game";
    }
}

trait Music
{
    function play() {
        echo "Playing music";
    }
}

class Player
{
    use Game, Music;
}

$player = new Player();
$player->play();

Nếu chúng ta cứ gọi hàm đơn thuần như những ví dụ trước. Thì tôi muốn hỏi các bạn là, Output trong trường hợp này là gì? 😄. Hãy bắt tay vào code vào tìm câu trả lời nhé. hé hé. Bài toàn là tôi có một class Player nhưng muốn in ra cả 2 trường hợp là chơi game và nghe nhạc thì tôi phải làm thế nào????

Giải pháp là đây:

<?php
class Player
{
    use Game, Music {
        Game::play as gamePlay;
        Music::play insteadof Game;
    }
}

$player = new Player();
$player->play(); //Playing music
$player->gamePlay(); //Playing a game

Nguồn: https://viblo.asia/p/php-traits-roavrwXjGRM

Leave a Reply

Your email address will not be published.