LARAVEL中TRAIT的使用教程詳解

LARAVEL框架不用多說了,那麽wait命令如何使用呢,我相信各位朋友不太懂吧,今天小編來爲各位介紹LARAVEL中TRAIT的使用教程吧。

看看PHP官方手冊對Trait的定義:

自 PHP 5.4.0 起,PHP 實現了代碼複用的一個方法,稱爲 traits。

Traits 是一種爲類似 PHP 的單繼承語言而准備的代碼複用機制。Trait 爲了減少單繼承語言的限制,使開發人員能夠自由地在不同層次結構內獨立的類中複用方法集。Traits 和類組合的語義是定義了一種方式來減少複雜性,避免傳統多繼承和混入類(Mixin)相關的典型問題。

Trait 和一個類相似,但僅僅旨在用細粒度和一致的方式來組合功能。Trait 不能通過它自身來實例化。它爲傳統繼承增加了水平特性的組合;也就是說,應用類的成員不需要繼承。


官方手冊也舉了兩個例子:

Trait用法示例

<?php
trait ezcReflectionReturnInfo {
function getReturnType() { /*1*/ }
function getReturnDescription() { /*2*/ }
}

class ezcReflectionMethod extends ReflectionMethod {
use ezcReflectionReturnInfo;
/* ... */
}

class ezcReflectionFunction extends ReflectionFunction {
use ezcReflectionReturnInfo;
/* ... */
}
?>

Trait的優先級

從基類繼承的成員被 trait 插入的成員所覆蓋。優先順序是來自當前類的成員覆蓋了 trait 的方法,而 trait 則覆蓋了被繼承的方法。

從基類繼承的成員被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆蓋。其行爲 MyHelloWorld 類中定義的方法一致。優先順序是當前類中的方法會覆蓋 trait 方法,而 trait 方法又覆蓋了基類中的方法。

<?php
class Base {
public function sayHello() {
echo 'Hello ';
}
}

trait SayWorld {
public function sayHello() {
parent::sayHello();
echo 'World!';
}
}

class MyHelloWorld extends Base {
use SayWorld;
}

$o = new MyHelloWorld();
$o->sayHello();
?>

以上例程會輸出:

Hello World!

以上內容來自PHP官網手冊。

Trait在Laravel中的使用

Laravel中大量使用Trait特性來提高代碼的複用性,本文只是從某個Laravel專案中舉個例子。

比如在一個PageController.php控制器中有個show方法:

PHP

public function show($slug)
{
$page = PageRepository::find($slug);
$this->checkPage($page, $slug);

return View::make('pages.show', ['page' => $page]);
}
這裏PageRepository::find()方法就是使用的一個Trait的方法,在PageRepository.php中使用命名空間聲明及引入:

PHP

namespace GrahamCampbell\BootstrapCMS\Repositories;

use GrahamCampbell\Credentials\Repositories\AbstractRepository;
use GrahamCampbell\Credentials\Repositories\PaginateRepositoryTrait;
use GrahamCampbell\Credentials\Repositories\SlugRepositoryTrait;

class PageRepository extends AbstractRepository
{
use PaginateRepositoryTrait, SlugRepositoryTrait;
// 此處省略800子
}

其中SlugRepositoryTrait這個Trait定義了find方法:

PHP


trait SlugRepositoryTrait
{
/**
* Find an existing model by slug.
*
* @param string $slug
* @param string[] $columns
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function find($slug, array $columns = ['*'])
{
$model = $this->model;

return $model::where('slug', '=', $slug)->first($columns);
}
}

這樣就可以在控制中使用Trait了,很好的實現了代碼的複用。

個人理解:

在一個類中使用Trait,就相當于這個類也有了Trait中定義的屬性和方法。Traits的使用場景是如果多個類都要用到同樣的屬性或者方法,這個時候使用Traits可以方便的給類增加這些屬性或方法,而不用每個類都去繼承一個類,如果說繼承類是豎向擴展一個類,那麽Traits是橫向擴展一個類,從而實現代碼複用。

有用的鏈接:

Traits可以理解爲一組能被不同的類都能調用到的方法集合,但Traits不是類!不能被實例化。先來例子看下語法:


<?php
trait myTrait{
function traitMethod1(){}
function traitMethod2(){}
}
//然後是調用這個traits,語法爲:
class myClass{
use myTrait;
}
//這樣就可以通過use myTraits,調用Traits中的方法了,比如:
$obj = new myClass();
$obj-> traitMethod1 ();
$obj-> traitMethod2 ();

  接下來,我們探究下爲什麽要用traits,舉個例子,比如有兩個類,分別爲business(商務者)和Individual(個人),它們都有地址的屬性,傳統的做法是,再抽象出一個這兩個類都共同有特性的父類,比如client,在client類中設置訪問屬性address,business和individual分別繼承之,如下代碼:


// Class Client
class Client {
private $address;
public getAddress() {
return $this->address;
}
public setAddress($address) {
$this->address = $address;
}
}
class Business extends Client{
//這裏可以使用address屬性
}
// Class Individual
class Individual extends Client{
//這裏可以使用address屬性
}

但假如又有一個叫order類的,需要訪問同樣的地址屬性,那怎麽辦呢?order類是沒辦法繼承client類的,因爲這個不符合OOP的原則。這個時候traits就派上用場了,可以定義一個traits,用來定義這些公共屬性。


// Trait Address
trait Address{
private $address;
public getAddress() {
eturn $this->address;
}
public setAddress($address) {
$this->address = $address;
}
}
// Class Business
class Business{
use Address;
// 這裏可以使用address屬性
}
// Class Individual
class Individual{
use Address;
//這裏可以使用address屬性
}
// Class Order
class Order{
use Address;
//這裏可以使用address屬性
}

更多相關文章
  • linux中安裝RHEV-M的教程詳解
    紅帽的虛擬化産品 RHEV 分爲 RHEV-H 和 RHEV-M.前者實際就是一個輕量級的 RHEL+KVM 組合,外加一些基本的配置工具如 libvirt 等,下面我們一起來看看linux中安裝RHEV-M的教程詳解一.yum源配置安裝rhev-m需要配置RHEV-M.RHEV-H.Supplem ...
  • Linux系統PHP安裝curl擴展支持https教程詳解
    安裝curl的方法小編介紹過不少了,今天我們來看一篇在Linux系統PHP安裝curl擴展
  • 本文章來爲各位介紹一篇關于linux下利用SHC加密shell教程詳解,希望這篇教程能夠對各位同學帶來有效的幫助.SHC代表shell script compiler,即shell腳本編譯器.通過SHC編譯過的腳本程序對普通用戶而言是不讀的,因此如果你想保護你的代碼(例如含有密鑰),則可以考慮SHC
  • 一篇關于java中vector與hashtable操作詳解,vector與hashtable是線程安全的,主要是java對兩者的操作都加上了synchronized,有需要了解這兩個功能的同學可以進來看看.衆所周知,java中vector與hashtable是線程安全的,主要是java對兩者的操作都
  • jsp中freemarker 數字格式化詳解 有需要的朋友可參考一下.一.使用內建函數 c 特點:不管其表現形式是怎樣的( 代碼如下 例如"123,456.123,456". "123 456.123 456". "
  • 負載均衡有時可以使用nginx或apache來實現了,但有時有些朋友喜歡使用lvs來實現,下面我就來爲各位介紹Linux下負載均衡軟件LVS配置(VS/TUN)教程詳解DIP:192.168.199.230VIP:192.168.199.235RIP:192.168.199.231(232)負載均衡
  • 下文爲各位簡單的介紹Centos下安裝配置Puppet教程詳解,希望下文對各位有幫助puppet是一種Linux.Unix.windows平台的集中配置管理系統,使用自有的puppet描述語言,可管理配置文件.用戶.cron任務.軟件包.系統服務等.puppet把這些系統實體稱之爲資源,puppet
  • 文章分享一篇關于自己的學習筆記,oracel中字符串分割成集合詳解有需要學習的同學可以看看.首先分別使用兩種方式構造兩個函數 代碼如下 -- use conventional plsqlcreate or replace function f_str2list_pls( p_str varchar2
一周排行