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. IOS中UITableViewCell使用详解

    IOS中UITableViewCell使用详解 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(N ...

  2. HDU1502 Regular Words DP+大数

    要是c语言可以和java一样写大数就好了,或者我会写重载就好了,最后还是只能暴力一把. 开始写的记忆化搜索,然而n=10就超过LL了 #include<cstdio> #include&l ...

  3. PAT 1016 部分A+B C语言

    1016. 部分A+B (15) 正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA.例如:给定A = 3862767,DA = 6,则A的“6部分”PA是66,因为A中有2个6 ...

  4. django-redis 中文文档

    Andrey Antukh, niwi@niwi.be 4.7.0 翻译: RaPoSpectre 1. 介绍 django-redis 基于 BSD 许可, 是一个使 Django 支持 Redis ...

  5. cratedb json 数据导入

    基本环境的搭建,可以参考相关文档,或者直接使用docker 安装 docker run -d -p 4200:4200 crate 导出mongodb数据(可选,同时使用工具进行数据类型转换) mon ...

  6. myeclipse越来越卡了怎么回事啊?

    去掉拼写检查:windows->preferences->General->Editors->Text Editors->Spelling 将“Enable spell ...

  7. System.IO.Path类

    System.IO.Path为路径的操作封装了很多很有的东西,利用该类提供的方法能够快速处理路径操作的问题.下面详细了解一下. 1.属性 属性太复杂了,反映什么系统平台的信息,看不懂,等以后看得懂了再 ...

  8. Sql Server中的事务隔离级别

    数据库中的事物有ACID(原子性,一致性,隔离性,持久性)四个特性.其中隔离性是用来处理并发执行的事务之间的数据访问控制.SqlServer中提供了几种不同级别的隔离类型. 概念 Read UnCom ...

  9. 再记录一次delete出错的经历

    调试的时候进行到delete语句时出现问题,我做的操作是在函数体内用int*申请了N个内存空间,这让我十分纳闷,为什么不能delete呢? 回忆到之前delete出错也遇过一次问题 手动封装OpenC ...

  10. generatorConfig.xml

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration ...