1. 程式人生 > >php中traits學習筆記

php中traits學習筆記

mina markdown 組織結構 public access 類繼承 ams requests class

traits學習

越來越多的框架和代碼開始使用traits方式去組織一些功能,這是非常高效的代碼組織結構。

通過trait來減少不必要的類繼承關系,讓代碼更加復用,形成可以拔插的代碼集合。

通過逗號分隔,在 use 聲明列出多個 trait,可以都插入到一個類中。

單個的例子:

<?php

trait Seller
{
    public function sell()
    {
       print_r("sell all goods");       
    }   
}

class MySeller
{
    use Seller; 
}


$seller = new MySeller();
$seller->sell();

多個trait的例子:

<?php
trait Money
{
    public function show()
    {
        echo "200$";
    }
}

trait Factory
{
    public function run()
    {
        print_r("running all");
    }
}

class User
{
    use Money, Factory;
    
    public function show()
    {
        echo "I am an user";
    }
} 

$user = new User();
$user->show(); // => I am an user

當引入trait的類也有同名方法或者函數,那麽當前類的該方法會覆蓋trait中的同名方法。

如上面這個例子中User類和Money trait都有show方法,則執行之後調用的是User類的show方法,打印出"I am an user"的內容。

但是如果兩個 trait 都插入了一個同名的方法,如果沒有明確解決沖突將會產生一個致命錯誤。我們需要明確指定是否某個trait的方法或者盡量不要讓不同trait裏面存在同名方法。

1.使用 insteadof 操作符來明確指定使用沖突方法中的哪一個。例如:

<?php
trait Token
{
    public function toString($var)
    {
        return (string)$var . "_token";
    }
    
    public function tips()
    {
        print_r("Token tips!");
    }
}

trait Tester
{
    public function toString($var)
    {
        return (string)$var . "_test";
    }
    
    public function tips()
    {
        print_r("Tester tips");
    }
}

class Controller
{   
    use Token, Tester {
        Token::toString insteadof Tester;
        Tester::tips insteadof Token;
    }
}

$con = new Controller();
$con->toString(‘hello‘);
$con->tips(‘my god!‘);

或者使用別名方式去避免同名問題,如:

class Controller
{
    user Token, Tester {
        Token::toString as toTokenString;
        Tester::tips as testerTips;
    }
}

以上都是一些理論案例,實際上一些優質和現代的php框架已經在使用trait方式組織整個代碼。典型的就是laravel。比如/www/larblog/app/Http/Controllers/Controller.php:

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesResources;

class Controller extends BaseController
{
    use AuthorizesRequests, AuthorizesResources, DispatchesJobs, ValidatesRequests;
}

這裏就使用了四個trait.

php中traits學習筆記