laravel 框架大量使用了traits. 简单举几个例子:

在Eloquent中使用了trait 。然后在model初始化的时候,有个boot方法,会自动判断当前的类用了哪些trait。然后得到一个数组。程序会遍历这个数组,寻找有没有符合 "bootTraitName"的方法(在trait中定义),如果有就执行。

/**
* Boot all of the bootable traits on the model.
*
* @return void
*/
protected static function bootTraits()
{
foreach (class_uses_recursive(get_called_class()) as $trait) {
if (method_exists(get_called_class(), $method = 'boot'.class_basename($trait))) {
forward_static_call([get_called_class(), $method]);
}
}
}

Eloquent用这种方法,在初始化一个model的时候,就可以做许多自动加载. laravel自带的功能中,softDelete就是通过trait来实现的。简单来说,use了softDelete的model,会在boot的时候自动执行bootSoftDelete,然后该方法在model所有的查询都默认加入一个判断deleted_at 字段的环节,以只调取未被删除的数据。

/**
* Boot the soft deleting trait for a model.
*
* @return void
*/
public static function bootSoftDeletes()
{
static::addGlobalScope(new SoftDeletingScope);
}

这种做法提供了很多便利,也提供了trait的使用示范。

举个简单的例子: 我们可以用这种方法 , 给model加载一个自动清除缓存的trait . 在每一个模型每次saved之后,自动刷新它的缓存:

trait ModelCache {

    public static function bootModelCache(){
static::saved(function($model){
$cacheKey = get_class($model).'_'.$model->id;
Cache::forget($cacheKey);
});
} }

trait在laravel的其它场景中也经常使用。例如User模型,是Laravel用来做身份验证的驱动。与身份验证的相关方法就是用一个trait来加载的。

<?php

namespace Illuminate\Auth;

trait Authenticatable
{
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
} ................. /**
* Get the token value for the "remember me" session.
*
* @return string
*/
public function getRememberToken()
{
return $this->{$this->getRememberTokenName()};
} }

这样当我们需要换别的模型,别的控制器做验证驱动,只要写一行use 代码,就自动得到了相关方法。

laravel使用trait还有一个比较典型的,就是dispatch。主要在laravel的controller中调用了这个trait。这样laravel的控制器就可以用$this->dispatch() 直接来调度任务。

trait DispatchesJobs
{
/**
* Dispatch a job to its appropriate handler.
*
* @param mixed $job
* @return mixed
*/
protected function dispatch($job)
{
return app('Illuminate\Contracts\Bus\Dispatcher')->dispatch($job);
} ...........
}

任何一个类只要use了这个DispatchJob的trait,都能用同样的调度方法(其实就是用app()得到了一个dispatch的单例)。

灵活使用trait , 还是能创造各种魔法 . 我有一个设想就是通过模仿laravel的trait机制实现的 .

简单来说 , 在做一个复杂的资讯站时 , 可能要创建许多种model . 然而每个model 总有一部分模块是一样的,例如:

  • 文章(标题,作者,正文)

  • 图片组(图片,简介)
  • 视频(标题,来源,源码,简介)
  • 添加到tag
  • 相关专题
  • 等等

创建model时,重复添加这些字段是一个很头疼的工作. 而现在,我们可以用trait:

abstract class Installer {

    //引用文章,图片,视频相关字段的构造trait
use ArticleTrait,ImageTrait,VideoTrait; /**
* 创建数据表
*/
protected function CreateTable()
{ //用Schema创建数据表
Schema::Create($this->table,function(Blueprint $table){ //生成默认字段
$table = $this->makeDefaultFields($table); //生成trait中的字段
$table = $this->makeTraitFields($table); }); } /**
* 生成默认字段
*/
protected function makeDefaultFields(Blueprint $table)
{
$table->increaments('id');
$table->timestamps();
return $table;
} /**
* 按照trait内的方法,生成模块的字段
*/
protected function makeTraitFields(Blueprint $table)
{
foreach (class_uses_recursive(get_called_class()) as $trait) { //如果trait内有 makeTraitNameFields方法, 就用该方法生成字段
if (method_exists($this, $method = 'make'.class_basename($trait).'Fields')) {
$table = $this->{$method}($table);
} } return $table;
} }

这样 , 建完几个标准的trait后, 要建其它复杂的模型,代码上就非常简单了

Laravel 在哪些地方使用了 trait ?的更多相关文章

  1. Laravel trait 使用心得

    trait 是在PHP5.4中为了方便代码复用的一种实现方式,但目前我在看的的PHP项目中较少看的有程序员去主动使用这个实现方式,在laravel中有很多 trait 的使用,关于trait 在 la ...

  2. Laravel trait的使用

    trait 是在PHP5.4中为了方便代码复用的一种实现方式,但目前我在看的的PHP项目中较少看的有程序员去主动使用这个实现方式,在laravel中有很多 trait 的使用,关于trait 在 la ...

  3. PHP trait 特性在 Laravel 中的使用个人心得

    trait 是在PHP5.4中为了方便代码复用的一种实现方式,但目前我在看的的PHP项目中较少看的有程序员去主动使用这个实现方式,在laravel中有很多 trait 的使用,关于trait 在 la ...

  4. 如何在 Laravel 中灵活的使用 Trait

    如何在 Laravel 中灵活的使用 Trait  Laravel/ 3个月前/  1740 /  4 / 更新于 3个月前   @这是小豪的第九篇文章 好久没有更新文章了,说好了周更结果还是被自己对 ...

  5. Laravel 5.0 之命令及处理程序

    本文译自 Matt Stauffer 的 系列文章 . 本文中涉及的新功能都是关于 Commands 的,这些特性在 Laravel 旧版本中已经有了,但是在 Laravel 5.0 中变得更加好用了 ...

  6. laravel query builder/ Eloquent builder 添加自定义方法

    上次干这事已经是一年前了,之前的做法特别的繁琐.冗余,具体就是创建一个自定义 Builder 类,继承自 Query\Builder,然后覆盖 Connection 里面获取 Builder 的方法, ...

  7. Laravel学习笔记之PHP反射(Reflection) (上)

    Laravel学习笔记之PHP反射(Reflection) (上) laravel php reflect 2.1k 次阅读  ·  读完需要 80 分钟 3 说明:Laravel中经常使用PHP的反 ...

  8. Laravel 精选资源大全

    原文链接  必备品 文档:Documentation API:API Reference 视频:Laracasts 新闻:Laravel News 中文文档 Laravel学院– Laravel 5. ...

  9. TODO:Laravel 内置简单登录

    TODO:Laravel 内置简单登录 1. 激活Laravel的Auth系统Laravel 利用 PHP 的新特性 trait 内置了非常完善好用的简单用户登录注册功能,适合一些不需要复杂用户权限管 ...

随机推荐

  1. Vitya in the Countryside

    Every summer Vitya comes to visit his grandmother in the countryside. This summer, he got a huge war ...

  2. nexus 使用Raw Repositories 进行maven site 发布

    实际项目中我们可能需要进行maven 项目的site 文档发布,一般的处理是生成之后,然后在进行发布到一个静态 服务器进行页面访问,nexus3 提供了一个Raw Repositories 很方便可以 ...

  3. <script type="text/template">是干什么的,为什么要把html写在js中? 这是什么编程语言风格,都能这样用吗?

    这一段存放了一个模板.在js里面,经常需要使用js往页面中插入html内容.比如这样: var number = 123; $('#d').append('<div class="t& ...

  4. c++中for的四种用法

    #include <algorithm> #include <vector> #include <iostream> using namespace std; in ...

  5. 【转】让开发变得简单一点- Visual Studio 2010几个让人印象深刻的新功能

    原文网址:http://xhinker.blog.51cto.com/640011/313055/ 引言 "我们的目标,不仅仅是做出几个新功能,而是要回答一个问题:'如何让现在的开发人员生活 ...

  6. 【转】MFC String处理

    原文网址:http://www.cnblogs.com/lisuyun/p/3399232.html C/C++获取文件后缀名并且比较 以下这段是VC中过去文件后缀名的方法 1.CString Get ...

  7. string学习

    来自:http://www.cnblogs.com/kkgreen/archive/2011/08/24/2151450.html 0,new是创了两个对象,一个在堆,一个在常量池 1,变量+字符串= ...

  8. 学习OCI编程

    转自:http://kulong0105.blog.163.com/blog/static/174406191201162145944574/ 最近公司做的一个项目,要处理海量数据,数据是存放在Ora ...

  9. Serv-u只开放21端口连接不上解决方案

    在Serv-U的Local Server -> Settings -> Advanced -> PASV port range里, 填入给PASV模式使用的本地端口范围,如60000 ...

  10. py基础4--迭代器、装饰器、软件开发规范

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1. 列表生成式,迭代器&生成器 列表生成式 我现在有个需求, ...