Laravel 基础知识
文章目录
php 框架运行的核心三步
- 从入口进入 index.php
- 解析 url,匹配路由
- 根据路由,调用控制器,渲染视图
tip: 在第一步到第二步之间,会有更多的操作。比如自动加载,容器初始化等。这些都是为了后面的准备。
Laravel
发音:
Laravel: /ˈlærəvel/【/let 罗 否/】
Lumen: /lu 门/
- Laravel 是个功能齐全的全栈框架,学习她相当于你在学习成为全栈工程师。
- 框架知识分类
底层实现知识 —— 如服务容器、服务提供器、Facades、Contracts、Repository 等
框架使用知识 —— 如用户注册登录、邮件发送、数据模型的 CRUD、用户数据获取等
Artisan
Artisan 是 Laravel 内置的命令行接口。它提供了一些有用的命令协助您开发,它是由强大的 Symfony Console 组件所驱动。利用它,我们可以快速的新建 Controller、Model等类。
|
|
OTHER
-
框架核心内容
-
Laravel 服务容器
app(): app(SlugTranslateHandler::class) => 获取应用实例
- 类别名
1 2 3
// config/app.php 示例 在 config.aliases 加上 'Auth' => Illuminate\Support\Facades\Auth::class 后 在整个项目上可以直接用 \Auth::id() 方式获取当前用户id,可减少 use 的使用。
-
.editorconfig文件:代码风格配置
配置好代码风格后,在vs code上安装扩展EditorConfig for VS Code,这样就可以了。
-
tinker: 是 Laravel 包含的一个强大 REPL,REPL 是 Read Eval Print Loop 的缩写,它是一种交互式 shell(即可交互式的编程环境),它接受单个用户输入,运行它们,并将结果返回给用户。
-
使用npm run production编译sass、js等文件,可以大大压缩js和css等文件的大小。
-
Route::resource(‘users’, ‘UsersController’),resource 方法将遵从 RESTful 架构为用户资源生成路由。该方法接收两个参数,第一个参数为资源名称,第二个参数为控制器名称【隐性路由模型绑定】
- 上面代码将等同于:
- Route::get('/users', ‘UsersController@index’)->name(‘users.index’); // 列表
- Route::get('/users/{user}', ‘UsersController@show’)->name(‘users.show’); // 信息展示页面
- Route::get('/users/create', ‘UsersController@create’)->name(‘users.create’); // 新增页面
- Route::post('/users', ‘UsersController@store’)->name(‘users.store’); // 保存新增功能
- Route::get('/users/{user}/edit', ‘UsersController@edit’)->name(‘users.edit’); // 编辑页面
- Route::patch('/users/{user}', ‘UsersController@update’)->name(‘users.update’); // 保存编辑功能
- Route::delete('/users/{user}', ‘UsersController@destroy’)->name(‘users.destroy’); // 删除功能
-
policy: 授权策略,用于做权限控制
php artisan make:policy UserPolicy
blade使用授权策略:@can(‘授权策略类的函数’, ‘授权策略类对应模型的实例’),eg: @can(‘update’, $user) @endcan
控制器端使用授权策略:$this->authorize(‘update’, $user);
Gates 和 Policies
Laravel 授权的方式主要分两种:Gates 和策略(Policies)。
Gates 和策略的关系像路由和控制器的。Gates 提供基于路由的授权方式;而策略将针对某个资源的操作逻辑组织起来,放在一个地方管理
我们不需要在「项目里的授权,是选择使用 Gates,还是选择使用策略呢?」这个问题上纠结。许多项目里,都会混用这两种授权方式,而且运行良好。基本上,使用 Gates 的地方都是资源不相关的,比如查看管理员面板页;相反,策略是资源相关的,当你是具体授权某个资源的操作权限时,使用策略是没错啦。
-
隐性路由模型绑定:传输id,Laravel框架直接去获取id的实例对象
-
关联方法 Vs. 动态属性
动态属性: eg: 模型类可以全局使用$this->数据库字段名
-
Eloquent ORM
-
Eloquent 模型约定
1 2 3 4 5 6 7 8
// $fillable 可以看作批量赋值的「白名单」, 你也可以使用 $guarded 属性来实现。 $guarded 属性包含的是不允许批量赋值的数组。也就是说, $guarded 从功能上将更像是一个「黑名单」。 protected $connection = 'mysql_middle_office'; protected $table = 'oat_customer'; protected $guarded = ['customer_id']; protected $primaryKey = 'customer_id'; // Eloquent 也会假设每个数据表都有一个名为 id 的主键列。你可以定义一个受保护的 $primaryKey 属性来重写约定。 public $incrementing = false; // 如果您希望使用非递增或非数字的主键则需要设置公共的 $incrementing 属性设置为 false。 protected $keyType = 'string'; // 如果你的主键不是一个整数,你需要将模型上受保护的 $keyType 属性设置为 string
-
本地作用域:允许我们在模型中定义通用的约束集合以便在应用中复用。要定义这样的一个作用域,只需简单在对应 Eloquent 模型方法前加上一个 scope 前缀,作用域总是返回 查询构建器。一旦定义了作用域,则可以在查询模型时调用作用域方法。在进行方法调用时不需要加上 scope 前缀。
-
模型关联:默认关联数据是懒加载,使用预加载方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// 预加载方式1 // 此循环将执行一个查询,用于获取全部书籍,然后为每本书执行获取作者的查询。如果我们有 25 本书,此循环将运行 26 个查询:1 个用于查询书籍,25 个附加查询用于查询每本书的作者。 // 谢天谢地,我们能够使用预加载将操作压缩到只有 2 个查询。在查询时,可以使用 with 方法指定想要预加载的关联(de方法名) // $books = App\Book::all(); // 懒加载 $books = App\Book::with('author')->get(); // 预加载 foreach ($books as $book) { echo $book->author->name; } // 执行预加载的sql示例 // select * from books // select * from authors where id in (1, 2, 3, 4, 5, ...) // 预加载方式2:有可能你还希望在模型加载完成后在进行渴求式加载。举例来说,如果你想要根据某个条件动态决定是否加载关联数据,那么 load 方法对你来说会非常有用 $books = App\Book::all(); if ($someCondition) { $books->load('author', 'publisher'); // $book->loadMissing('author', 'publisher'); // 希望关联关系仅在尚未加载时才去加载,以避免无效重复加载 }
- 访问器&修改器:当你在 Eloquent 模型实例中获取或设置某些属性值的时候,访问器和修改器允许你对 Eloquent 属性值进行格式化。
- API资源:当构建 API 时,你往往需要一个转换层来联结你的 Eloquent 模型和实际返回给用户的 JSON 响应。
- 常用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
$user = App\Models\User::first(); # Laravel 5.8 查询存放反斜杠内容字段,需特殊处理 $query->where('mall_order_infos.order_type', 'like', 'App\\Models\\Activity\\PreOrder'); # 使用 isDirty() 方法确定模型或给定属性是否已被修改 $user->name = 'Michael'; $user->isDirty('title'); # true # 获取记录的原始属性 $user->getOriginal('name'); # Laravel 的模型可以通过 query 方法获取一个 Builder 实例,这种写法在一些场景下是有用的,比如说自定义过滤器 $query = User::query(); if( $request->name ){ $query->where('name', $request->name); } # 打印执行 SQL 日志 DB::enableQueryLog(); dd(DB::getQueryLog()); # 打印 SQL 语句 $sql = User::where('age', 18)->toSql(); dd($sql);
-
-
模型观察器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# 模型观察器 - 对模型的生命周期内的多个时间点进行监控,分别有 ~ing 和 ~ed 事件 // creating, created, updating, updated, saving, // saved, deleting, deleted, restoring, restored - 每个监控方法接收 model 作为唯一参数 # 使用观察器 - 创建观察器文件,一个普通类,不需要继承什么 - 针对需要的事件,编写对应的 ~ing 或 ~ed 方法,方法接收 model 作为唯一参数 # 在 AppServiceProvider 中注册 // 在 boot 方法中 YourModel::observe(YourModelObserver::class); # 在模型下的 boot 方法中实现 无论模型何时初始化,静态 boot() 方法自动执行,所以它是一个添加行为或者绑定事件的理想所在。比如,在我们当前的案例中,模型中发生删除事件时自动删除一个相关图片。 public static function boot() { parent::boot(); //当删除时触发 self::deleted(function ($model) { Cache::forget(config('cache_keys.account') . $model->id); Cache::forget(config('cache_keys.account_wxid') . $model->wxid); }); }
-
Laravel Job 和 事件系统
1 2 3 4 5 6 7
- Job 和 队列 结合 Job既可以用作同步,也可以用作异步。 如果你想延迟执行一个操作,或者这个过程需要花费一段时间,那么就可以选择用Job,例如上传一个比较大的文件。 Job一般用在正在处理的事情。比如我们去银行办理业务,很多人排队等待,我们可以把这条队看成一个队列queue,把每一个人看成一个Job,服务人员会帮我们一个接一个的处理业务。办完了一个业务,系统会叫号叫到下一个人,执行下一个Job。每个人需要办理的业务都不一样,这就是每个Job需要完成的任务。 - Event 事件监听可以允许参与不同的角色。事件监听可以认为是特定事件发生的一个Job,一旦事件创建,监听器就会触发。事件可以理解成“当...”,“就...”。 一个事件可以被多个监听器监听,比如登录后,系统既要发送邮件,又要发送短信,这个时候,就可以建立一个登录事件,事件触发后,同事被发送邮件和发送短信监听到。
-
表单请求验证类:将表单字段验证逻辑从控制器中解耦
1 2 3 4 5 6 7 8
use App\Http\Requests\UserRequest; // 消息提示:with('success', '...') <=> session()->flash('success', '...') public function update(UserRequest $request, User $user) { $user->update($request->all()); return redirect()->route('users.show', $user->id)->with('success', '个人资料更新成功!'); }
-
…
-
Facades(读音:/fəˈsäd/ )为应用程序的 服务容器 中可用的类提供了一个「静态」接口。你不必 use 一大串的命名空间,也不用实例化对象,就能访问对象的具体方法。
- Facade 其实是一个容器中类的静态代理,他可以让你以静态的方式来调用存放在容器中任何对象的任何方法。
- 创建自定义 Facade: 写好一个新功能后,先自定义一个 Facade 类后,然后在 Providers/…Provider.php 文件中的 register 方法中,将服务绑定到服务容器中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
# 案例 # app/Services/SocketIO/WeChat.php <?php namespace App\Services\SocketIO; /** * socket io 版的事件接口 * Class WeChat * @package App\Services\SocketIO */ class WeChat { const TEXT_MSG_TYPE = 1; //文本 const IMAGE_MSG_TYPE = 2; //图片 const AUDIO_MSG_TYPE = 3; //音频 const VIDEO_MSG_TYPE = 4; //视频 const NAMECARD_MSG_TYPE = 22; //名片 const EMOJI_MSG_TYPE = 9; //表情 /** * 获取消息类型对应的uri * @return array */ public function getMsgTypeUris() { return [ self::TEXT_MSG_TYPE => '/api/send_message_v2', self::IMAGE_MSG_TYPE => '/api/send_image_v2', self::EMOJI_MSG_TYPE => '/api/send_emoji_v2', self::NAMECARD_MSG_TYPE => '/api/send_namecard', self::CHATROOM_INVITE_MSG_TYPE => '/api/invite_friend_to_chatroom', self::VIDEO_MSG_TYPE => '/api/send_video', ]; } } # app/Facades/WeChat.php <?php namespace App\Facades; use Illuminate\Support\Facades\Facade; class WeChat extends Facade { protected static function getFacadeAccessor() { return 'WeChat'; } } # app/Providers/AppServiceProvider.php: 将服务绑定到服务容器中 <?php namespace App\Providers; use App\Services\SocketIO\WeChat; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * @return void */ public function register() { $this->app->singleton('WeChat', function () { return new WeChat(); }); } } # config/app.php <?php 'providers' => [ App\Providers\AppServiceProvider::class, ], 'aliases' => [ 'WeChat' => App\Facades\WeChat::class, ],
-
消息通知类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
<?php use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Auth\MustVerifyEmail as MustVerifyEmailTrait use Auth; class User extends Authenticatable implements MustVerifyEmailContract { // use Notifiable; // trait 中的 notify 方法重命名为 laravelNotify use Notifiable { notify as protected laravelNotify; } } Auth::user()->notify(); // 推送消息通知 Auth::user()->notifications()->get(); // 获取该用户所有的通知列表 Auth::user()->readNotifications()->get(); // 获取已读的通知列表 Auth::user()->unreadNotifications()->get(); // 获取未读的通知列表 Auth::user()->unreadNotifications->markAsRead(); // 将未读标记为已读 Auth::user()->readNotifications->markAsRead(); // 将已读标记为纬度
-
Services层:使用 Traits 来为数据模型瘦身
namespace Models/Traits;
-
本地化(或者多语言系统处理方案)
- 客户端请求 API 时, 加上 HTTP 的 Accept-Language 头信息,便于服务器区分系统语言。
- 从接口的可扩展性、适用性和专业性上考虑,最合理的也是最推荐的做法是:API 既提供错误码,又提供本地化的错误消息。
- 另外,错误消息 默认 返回英文,也会是比较合理的最佳实践,当然最终视 API 业务逻辑而定。
-
切记:config目录里用 env() 获取环境变量,其他地方用 config() 获取环境变量。
- 因为线上环境启用 config 缓存后,config 文件夹外的 env 函数不起效果
-
开发环境记录程序执行的 sql 语句方案
1 2 3 4 5 6 7 8 9 10 11 12
// App\Providers\AppServiceProvider public function boot() { if (env('APP_ENV') == 'local') { DB::listen(function ($query) { $sql = str_replace("?", "'%s'", $query->sql); $sql = vsprintf($sql, $query->bindings); $sql = str_replace("\\", "", $sql); Log::info($sql); }); } }
-
Laravel 指定日志文件记录任意日志
1 2 3 4 5
use Illuminate\Support\Facades\Log; Log::getMonolog()->popHandler(); Log::useFiles(storage_path('logs/data_info_market.log'), 'info'); Log::info('==>id=1111');
-
使用 chunk(分块) 和 cursor(游标) 减少内存的使用量
词汇
- mass assignment => 批量赋值
- fillable => 用户可赋值字段,guarded => 仅保护字段
- reguarded => 保护,unguarded => 取消保护
- pivot => 它代表中间表的一个模型对象
规范
- 遵守『约定优于配置』设计范式
- 使用复数形式命名:控制器、数据库表名、文件夹名
- 其他使用单数形式命名,如model、policy、seeder
全局辅助方法
- session()
- redirect()
- csrf_token(), csrf_field()
- snake_case() => 驼峰法字符串格式化为下划线命名。
- config(‘app’) => 获取配置文件的数据,可以使用点语法获取具体参数
中间件
Laravel 中间件提供了一种方便的机制来过滤进入应用的 HTTP 请求。类似CI框架的钩子。
- auth: 控制已登录用户才能访问的函数
- guest:控制游客才能访问的函数
Auth 类
- use Auth; 等价于 use Illuminate\Support\Facades\Auth;
- Auth::loginUsingId(1); // 登录指定用户 ID 的用户到应用上
- Auth::user() // 获取当前用户实例
- Auth::check() // 判断是否已登录
- Auth::id() <=> Auth::user()->id; // 获取id
- Auth::once($credentials); // 只针对一次的请求来认证用户
- Auth::logout(); // 使用户退出登录(清除会话)
Blade
- Request::url() == route(‘categories.show’, 4 ) // 判断当前请求链接和某路由是否一致
- Blade 语法 {{ }} 会自动调用 PHP htmlspecialchars 函数来避免 XSS 攻击。
- Blade 的 {!! !!} 语法是直接数据,不会对数据做任何处理。
- @include(‘layouts._header’, []) , @includeWhen(Auth::check(), ‘layouts._header’, [])
项目实践案例
-
PhpStorm Ide Helper安装
-
1、在PhpStorm中搜索安装 Laravel Plugin
-
2、
composer require --dev barryvdh/laravel-ide-helper
-
3、如果你只在开发环境中安装「larave-ide-helper」,那么可以在「app/Providers/AppServiceProvider.php」的「register」方法中写入下面代码:
1 2 3 4 5 6 7
public function register() { if ($this->app->environment() === 'local') { $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class); } // ... }
-
4、
php artisan ide-helper:generate
- 为 Facades 生成 phpDocs 注释 -
5、
php artisan ide-helper:meta
- 为 PhpStorm 生成类路径提示文件
-
-
mergeBindings方式查询 和 子连接查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
// mergeBindings方式查询 $subQuery = MemberActivity::table(MemberActivity::getMonthTableName(strtotime('-1 month')))::query() ->where('chatroom_id', $chatroomId) ->select(['member_id', 'date']) ->orderByDesc('id'); $query = MemberActivity::table()::query() ->where('chatroom_id', $chatroomId) ->select(['member_id', 'date']) ->orderByDesc('id') ->union($subQuery); $queryUnionSql = $query->toSql(); $lastActivityData = DB::connection("mysql_big_data") ->table(DB::raw("($queryUnionSql) as temp")) ->mergeBindings($query->getQuery()) // 子查询语句参数实例化 ->groupBy('member_id') ->pluck('date', 'member_id') ->toArray(); // 子连接查询 public function getTraceLatestList(array $ownerAccountIds, array $bindAccountIds): array { $subQuery = \App\Models\Trace::query() ->select(DB::raw("max(id) max_id")) ->whereIn('account_id', $ownerAccountIds) ->whereIn('target_account_id', $bindAccountIds) ->groupBy(DB::raw("concat(account_id, '-', target_account_id)")); $ret = \App\Models\Trace::query() ->select([DB::raw("concat(traces.account_id, '-', traces.target_account_id) as account_key"), 'traces.content']) ->joinSub($subQuery, 'sub', function ($join) { $join->on('traces.id', '=', 'sub.max_id'); }) ->whereIn('traces.account_id', $ownerAccountIds) ->whereIn('traces.target_account_id', $bindAccountIds) ->pluck('traces.content', 'account_key') ->toArray(); return $ret; } // 子查询案例 $data = TableA::query() ->select($fields) ->whereIn( 'customer_id', TableB::query()->whereIn('account_id', $ownerAccountIds)->select(['customer_id']) ) ->orderByDesc('customer_id') ->paginate($params['per_page'])->toArray();
-
Laravel 数据库模式非 ORM 模式 获取的数据数组化方式
1 2 3 4 5 6 7 8 9 10
$data = DB::connection("mysql") ->table("table_name") ->where('id', 1) ->orderByDesc('created_at') ->take(100) ->get() ->map(function ($x) { // 关键地方 return (array) $x; }) ->toArray();
-
迁移文件表添加表注释
1 2 3 4 5
\DB::statement("ALTER TABLE `categories` comment '帖子分类'"); // 创建时间和更新时间 $table->timestamp('created_at', 0)->useCurrent(); $table->timestamp('updated_at', 0)->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
-
服务器环境修改了数据库密码、等配置时,需要执行下
php artisan optimize
# 重置配置和路由的缓存文件 -
Laravel 查询语句指定索引( mysql 强制索引)
1 2 3 4 5 6
$agents = Agent::query() ->from(\DB::raw('`agent` FORCE INDEX (`index_test`)')); ->join(\DB::raw('`user` FORCE INDEX (`user_id`)'), function ($join) use ($staffId) { $join->on('agent.user_id', '=', 'user.user_id'); }) ->get();
Laravel Install
-
方法一: 安装器安装
1 2 3 4 5
# 缺点不能安装指定版本,默认安装最新版本 composer global require "laravel/laravel-installer" lumen new test
-
方法二:通过 Composer Create-Project 命令安装,可以指定版本号
1 2 3
cd ~/www/ composer create-project laravel/laravel test --prefer-dist '5.8.*'
-
查看版本号
1 2 3
cd ~/www/your_project php ./artisan
Laravel 构建已有项目流程
-
修改配置文件 .env
包括数据库配置、邮箱配置、redis配置、时区配置等
-
组件安装
1
composer install
-
数据库表迁移和数据填充
1 2
# 执行数据库迁移和数据填充 php artisan migrate:refresh --seed
Laravel 创建新项目流程
-
框架安装
1 2 3
cd ~/Code/ composer create-project laravel/laravel laravel-test --prefer-dist '5.8.*'
-
更改 readme.md
-
统一代码风格
1 2 3 4
# .editorconfig 文件添加以下代码 [*.{js,html,blade.php,css,scss}] indent_style = space indent_size = 2
-
修改配置文件 .env
包括数据库配置、邮箱配置、redis配置、时区配置、语言包配置等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 配置时区 1. .env 文件添加:TIMEZONE="asia/shanghai" 2. 更改 config/app.php : 'timezone' => env('TIMEZONE', 'UTC'), # 添加中文语言包 1. composer require "overtrue/laravel-lang:~3.0" 2. 安装成功后,在 config/app.php 文件中将以下这一行: Illuminate\Translation\TranslationServiceProvider::class, 替换为: Overtrue\LaravelLang\TranslationServiceProvider::class, 3. .env 文件添加 : LOCALE="zh-CN" 4. 更改 config/app.php : 'locale' => env('LOCALE', 'en')
-
数据库表迁移和数据填充
1 2
# 执行数据库迁移和数据填充 php artisan migrate:refresh --seed
-
基础布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# Models mkdir app/Models mv app/User.php app/Models/User.php 在执行上面的操作之后,我们还需要执行下面这两个操作: 1、修改 Models/User.php 文件,更改 namespace 为我们新创建的文件夹路径。 2、编辑器全局搜索 App\User 替换为 App\Models\User。 # Views rm resources/views/welcome.blade.php mkdir resources/views/layouts touch resources/views/layouts/app.blade.php touch resources/views/layouts/_header.blade.php touch resources/views/layouts/_footer.blade.php mkdir resources/views/shared touch resources/views/shared/_messages.blade.php # 运行Laravel Mix vi resources/sass/app.scss => 删除 Fonts vi ./webpack.mix.js => 加上 version(),解决浏览器对静态文件的缓存问题 yarn config set registry https://registry.npm.taobao.org yarn install => 安装依赖 npm run watch-poll
-
加上授权策略自动发现的逻辑(Laravel 5.8)
1 2 3 4 5 6
// 自动授权默认会假设 Model 模型文件直接存放在 app 目录下,鉴于我们已将模型存放目录修改为 app/Models,接下来还需自定义自动授权注册的规则,修改 boot() 方法: // 在 app/Providers/AuthServiceProvider.php 中的 boot 方法中加上授权策略自动发现的逻辑 Gate::guessPolicyNamesUsing(function ($modelClass) { // 动态返回模型对应的策略名称,如:// 'App\Models\User' => 'App\Policies\UserPolicy', return 'App\Policies\\'.class_basename($modelClass).'Policy'; });
-
项目部署相关命令「可选」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
# 迁移队列任务执行失败记录表 php artisan queue:failed-table php artisan migrate # 迁移通知消息表 php artisan notifications:table # 安装 redis 依赖包 composer require predis/predis "~1.0" # 安装 HTMLPurifier,HTMLPurifier 本身就是一个独立的项目,运用『白名单机制』对 HTML 文本信息进行 XSS 过滤。这种过滤机制可以有效地防止各种 XSS 变种攻击。 composer require "mews/purifier:~2.0" php artisan vendor:publish --provider="Mews\Purifier\PurifierServiceProvider" # 构建系统管理员后台 composer require "summerblue/administrator:~1.1" php artisan vendor:publish --provider="Frozennode\Administrator\AdministratorServiceProvider" # Laravel开发者工具类 1. 代码生成器 > composer require "summerblue/generator:~1.0" --dev 2. 调试工具 > composer require "barryvdh/laravel-debugbar:~3.2" --dev 3. 账号切换工具:测试用户权限将会很方便 > composer require "viacreative/sudo-su:~1.1" --dev 4. 安装 Horizon, Horizon 是 Laravel 生态圈里的一员,默认只能在 local 环境中访问仪表盘,为 Laravel Redis 队列提供了一个漂亮的仪表板,允许我们很方便地查看和管理 Redis 队列任务执行的情况。 > composer require "laravel/horizon:~3.1" --dev > php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider" # 至此安装完毕,浏览器打开 http://hosts/horizon 访问控制台: > php artisan horizon # 队列监控,用来代替 Laravel 自带的 artisan queue:listen,需要常驻运行 > Tip: 需要注意的是,artisan horizon 队列工作的守护进程是一个常驻进程,它不会在你的代码改变时进行重启,当我们修改代码以后,需要在命令行中对其进行重启操作。 5. 查询日志组件:可以查看sql的输出 composer require overtrue/laravel-query-logger --dev
Laravel IDE Helper
Laravel IDE Helper 是一个极其好用的代码提示及补全工具,可以给编写代码带来极大的便利。
|
|