|
| 1 | +## 新特性trait在Laravel中的应用 |
| 2 | + |
| 3 | +## trait 是什么? |
| 4 | + |
| 5 | +Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。 |
| 6 | + |
| 7 | +Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承。 |
| 8 | + |
| 9 | +简单来说trait就是解决php不能实现多继承的。 |
| 10 | + |
| 11 | + |
| 12 | +## 具体的案例 |
| 13 | + |
| 14 | +如我们定义类的时候,很多都要做成单例模式,因此我们只需要定一个trait在需要单例的时候use trait就可以了。下面看下代码 |
| 15 | + |
| 16 | +```php |
| 17 | + |
| 18 | +trait Singleton { |
| 19 | + protected static $_instance; |
| 20 | + |
| 21 | + final public static function getInstance() { |
| 22 | + if(!isset(self::$_instance)) { |
| 23 | + self::$_instance = new static(); |
| 24 | + } |
| 25 | + |
| 26 | + return self::$_instance; |
| 27 | + } |
| 28 | + |
| 29 | + private function __construct() { |
| 30 | + $this->init(); |
| 31 | + } |
| 32 | + |
| 33 | + protected function init() {} |
| 34 | + |
| 35 | +} |
| 36 | + |
| 37 | + |
| 38 | +class Db { |
| 39 | + use Singleton; |
| 40 | + protected function init() { |
| 41 | + |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +``` |
| 46 | + |
| 47 | +## trait在Laravel中的应用 |
| 48 | + |
| 49 | +laravel中大量的使用到了trait,下面我来拿比较那用的的Laravel Auth来看,首先执行 |
| 50 | + |
| 51 | +```bash |
| 52 | +php artisan make:auth |
| 53 | +``` |
| 54 | + |
| 55 | +然后到app/Http/Controllers/Auth/ 目录下找到LoginController,你会发现LoginController中的代码比较少,只定义了一个use AuthenticatesUsers; 处理数据,登录之类的核心功能都不在这个控制器中。我们然后打开这个AuthenticatesUsers,你会发现所有有关login的功能都在这个文件里面。 |
| 56 | + |
| 57 | +那有同学就会感到疑问了,为什么不直接写到LoginController呢?下面我来给大家说下 |
| 58 | + |
| 59 | +AuthenticatesUsers 这个里面实现了根login的业务逻辑,但是呢?所有的可配置的参数,可重写改的方法你都可以在LoginController中就实现重写,这样代码不就简洁了嘛。我们随意找一个举例,我们重写login的验证加入极验验证。 |
| 60 | + |
| 61 | +```php |
| 62 | + |
| 63 | +namespace App\Http\Controllers\Auth; |
| 64 | + |
| 65 | +use Illuminate\Http\Request; |
| 66 | +use App\Http\Controllers\Controller; |
| 67 | +use Illuminate\Validation\ValidationException; |
| 68 | +use Illuminate\Foundation\Auth\AuthenticatesUsers; |
| 69 | + |
| 70 | +class LoginController extends Controller |
| 71 | +{ |
| 72 | + |
| 73 | + use AuthenticatesUsers; |
| 74 | + |
| 75 | + protected function redirectTo() |
| 76 | + { |
| 77 | + return '/'; |
| 78 | + } |
| 79 | + |
| 80 | + protected $gee; |
| 81 | + |
| 82 | + public function __construct(GeeCaptchaController $gee) |
| 83 | + { |
| 84 | + $this->gee = $gee; |
| 85 | + $this->middleware('guest')->except('logout'); |
| 86 | + } |
| 87 | + |
| 88 | + /** |
| 89 | + * 重写login验证逻辑,增加极验验证 |
| 90 | + * |
| 91 | + * @param \Illuminate\Http\Request $request |
| 92 | + * @return void |
| 93 | + */ |
| 94 | + protected function validateLogin(Request $request) |
| 95 | + { |
| 96 | + $this->validate($request, [ |
| 97 | + $this->username() => 'required|string', |
| 98 | + 'password' => 'required|string', |
| 99 | + ]); |
| 100 | + |
| 101 | + if (!$this->gee->verify()) { |
| 102 | + throw ValidationException::withMessages([ |
| 103 | + 'captcha' => '无效的验证码失效!', |
| 104 | + ]); |
| 105 | + } |
| 106 | + |
| 107 | + } |
| 108 | +} |
| 109 | + |
| 110 | +``` |
| 111 | + |
| 112 | +[示例代码下载链接](https://github.com/cxp1539/laravel-core-learn/blob/master/code/Class7.php) |
0 commit comments