laravel基础知识
composer dump
1、Csrft
指定路由不用通过CSRFT验证,文件路径
App/Http/Middleware/VerifyCsrftToken.php
2、4种基础路由的定义
Route::请求方式('uri', 匿名函数);
Route::请求方式('uri','控制器名称@操作方法');
#从服务器取出资源(一项或多项) select
Route::get($uri, $callback);
#在服务器新建一个资源insert
Route::post($uri, $callback);
#在服务器更新资源update
Route::put/patch($uri, $callback);
#从服务器删除资源delete
Route::delete($uri, $callback);
4种基础路由中,只有GET请求方法不进行CSRF验证,其他请求方式则需要CSRF验证
在routes/web.php增加路由
// get请求 它没有csrf验证 Route::get('/req', function () { return 'get请求'; }); // post请求 Route::post('/req', function () { return 'post请求'; }); // put请求 Route::put('/req', function () { return 'put请求'; }); // patch请求 Route::patch('/req', function () { return 'patch请求'; }); // delete请求 Route::delete('/req', function () { return 'delete请求'; });
同时多种请求的方式
Route::match(['get','post'], '/req', function () { // 打印方法 dump dump($_SERVER); });
·支持所有请求方式
// 支持所有请求方式 实际开放中不推荐这种方式 Route::any('/req', function(){ dump($_SERVER); });
2.1 csrf
模板中的csrf验证
{{csrf_token()}} # 这个没标签,纯token
@csrf # 这个有标签 新版用这个
{{ csrf_field() }} # 这个有标签 旧版用这个
3、路由参数
# 必填 Route::get('URL/{参数名称}','闭包函数或控制器响应方法标识'); # 可选 Route::get('URL/{参数名称?}','闭包函数或控制器响应方法标识'); # 参数限制 Route::get('URL/{参数名称}','闭包函数或控制器响应方法标识')->where(['参数名称'=>'正则']);
例子:ID只能是数字
Route::get('article/{id}', function($id){ echo $id; })->where(['id'=>'\d+']);
路由别名
// 路由别名 Route::get('/user/{id}', function($id){ return "当前用户id是:".$id; })->name('名字'); # 生成路由对应的URL地址 $url = route('路由名称');
例子:
// larval我一般用.来连接 Route::get('/req', function(){ return "当前用户"; })->name('index.req'); Route::get('/req1', function(){ // 用路由别名获取url地址 return route('index.req'); });
4、路由前缀
# 路由前缀 Route::group(['prefix'=>'admin'], function(){ Route::get('users', function(){ // 匹配 "/admin/users" URL }); });
# 普通写法 /*Route::get('sys/log', function(){ return 1; }); Route::get('sys/logout', function(){ return 2; }); Route::get('sys/index/index', function(){ return 3; }); Route::get('sys/index/welcome', function(){ return 4; });*/ # 使用路由前缀写法 Route::group(['prefix'=>'sys'], function(){ Route::get('log', function(){ // 匹配 "/sys/log" URL return 1; }); Route::get('index', function(){ // 匹配 "/sys/index" URL return 2; }); Route::group(['prefix'=>'index'], function(){ Route::get('index', function(){ // 匹配 "/sys/index/index" URL return 3; }); Route::get('welcome', function(){ // 匹配 "/sys/index/welcome" URL return 4; }); }); });
利用PHP 查看定义好的路由
php artisan route:list
5、 控制器文件命名和创建
注意:使用大驼峰命名,同时注意命名空间和基类控制器的引入
# 一般控制器
php artisan make:controller 控制器名Controller
# 资源控制器
php artisan make:controller 控制器名Controller -r [--resource]
例子:创建登陆控制器
# 一般控制器 php artisan make:controller LoginController # 资源控制器 php artisan make:controller LoginController -r # 包含目录的 php artisan make:controller Admin/LoginController
6、定义路由访问控制器中的方法
Route::请求方法(RUI,'[命名空间\]控制器类名@方法名');
例子:
// 路由控制器 // 前台登陆 如果类和在我们Controller根目录下,就不用加命名空间 Route::get('login', 'LoginController@index')->name('login'); // 在Controllers下面如果有目录中的控制器,则定义路由时一定要加命名空间 //Route::get('admin/article/{id}', 'Admin\ArticleController@index')->name('admin.index'); // 分组简化命名空间 Route::group(['namespace'=>'Admin'], function(){ Route::get('admin/article/{id}', 'ArticleController@index')->name('admin.index'); });
7、请求
Input类获取数据,通过接收用户输入的类:Illuminate\Support\Facades\Input来进行获取数据
Input::get('参数的名字','如果参数没有被传递,使用该默认值'); Input::all();// 获取所有的用户输入 Input::only([]); // 获取指定几个用户的输入 Input::except([]); // 获取指定几个用户的输入一位的所有参数 黑名单 Input::has('名称'); // 判断某个输入的参数是否存在 上述方法可获取get中的信息,也可获取Post中的信息
例子:
// GET来获取请求的数据 // 参数1 请求名称 , 参数2 默认值 $username = Input::get('username', '张三'); $password = Input::get('password', '123'); // 获取全部 dump(Input::all()); // 获取指定的字段 白名单 dump(Input::only(['username', 'age'])); // 排除掉不要的字段 黑名单 dump(Input::except(['username'])); // 判断一个字段是否存在 dump(Input::has('sex'));
Request获取数据
// 登陆处理2 依赖注入方式来获取 public function login2(Request $request) { // 获取指定字段 $username = $request->get('username', 'null'); $password = $request->get('password', 'null'); // 获取全部 dump($request->all()); // 指定获取的字段 白名单 dump($request->only(['username', 'password'])); // 排除掉不要的字段 黑名单 dump($request->except(['username'])); // 判断一个字段是否存在 dump($request->has('sex')); // 判断请求的类型 get post put delete http请求类型 dump($request->isMethod('get')); // $request类还可以获取cookie和文件上传 }
// 用到它,我们就一定会用到$request中的isMethod方法 Route::match(['get','post'], 'login2', 'LoginController@login2');
8、辅助函数获取Request
// 打印出所有request可用方法 dump(get_class_methods(request()));
9、设置cookie
laravel框架为了安全,它的cookie是加密的
# 设置cookie return response('')->cookie('id', '11','10','/'); # cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly); # 读取cookie echo request()->cookie('id');
10、重定向
# 路由别名 return redirect()->route('路由别名',['id'=>1]); return redirect(route('getck'));
11、返回json数据
// 参数1 数组
// 参数2 返回的http状态码
return response()->json([ 'name' => 'xiaohong', 'age' => 22, ],201);
12、分配数据到模板
view('模板文件名称', 关联数组); view('模板文件名称', compact('变量名1', '变量名2')); view('模板文件名称')->with(关联数组);
例子:
// 一定要写模板的名称 /resources/views/index.blade.php //return view('index'); // 视图分模块 官方不推荐 //return view('html/index'); // 视图分模块 推荐这种 return view('html.index'); $data = ['id'=>1, 'name'=>'哈哈']; # 推荐compact来解决 return view('html.index', compact('data')); # with来传 return view('html.index')->with(['data'=>$data]); // 视图分模块 推荐这种 return view('html.index', ['data'=>$data]); <p>{{$data['id']}}</p> <p>{{$data['name']}}</p>
12、三元运算符
{{$name or 'Default'}} 等价于 <?php echo isset($name)?$name:'default'?>
例子
{{ $data['age'] or 'Default' }} {{ isset($data['age']) ? $data['age'] : 'Default' }}
13、未转义输出
如果变量信息里边如果有Html标记信息,在输出的时候html标记被转化为符号实体了,而没有被浏览器解析掉,如果希望看到被浏览器解析后的内容,就需要设置两个感叹号
例如:
$title = "<a href='http://www.baidu.com'>百度</a>"; {!!$变量!!}
14、原始形态输出(原样输出)
由于很多JavaScript框架都是用花括号来表明所提供的表达式,所以你可以使用@符号来告知Blade渲染引擎你需要保留这个表达式原始形态
@{{$变量名}}
15、使用函数
可以在blade模板中直接使用php函数
{{php 函数名()}}
16、if语句
return view('html.index')->with(['data'=>$data]); @if (count($records) === 1) 我有一条记录! @elseif (count($records) > 1) 我有多条记录 @else 我没有任何记录! @endif
17、循环
@foreach ($users as $user) <p>此用户为{{$user->id}}</p> # 如果传过来的就是数组那么我们就用 <p>{{$user['id']}}</p> @endforeach ------------------------ @forelse ($users as $user) <li>{{$user->name}}</li> # 如果传过来的就是数组那么我们就用 <p>{{ $user['id'] }}</p> @empty
18、模板包含
@include('public.header') # public 表示 views 下面的public目录 # header 表示在views/public/header.blade.php文件
19、模板继承
直接上案例
文件在views/public/main.blade.php
<head> <title>@yield('title')</title> <script></script> @yield('css') </head> <body> <h3>头部</h3> @yield('content') <h3>底部</h3> @yield('js') </body>
html1.blade.php
@extends('public.main') {{--用法1--}} @section('title','我就是html1') {{--用法2 双标签--}} @section('content') <h3>我就是html1</h3> @endsection
20、表单验证
view
<form action="{{ route('user.adduser') }}" method="post" class="form-horizontal"> {{--{{csrf_token()}}--}} @csrf {{--{{ csrf_field() }}--}} <div class="form-group"> <label class="col-sm-2 control-label">帐号:</label> <div class="col-sm-6"> <input type="text" name="username" class="form-control" value="{{old('username')}}"> </div> <div class="col-sm-4"> 我就是一个提示 </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">密码:</label> <div class="col-sm-6"> <input type="text" name="password" value="" class="form-control"> </div> <div class="col-sm-4"> 我就是一个提示 </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">确认密码:</label> <div class="col-sm-6"> <input type="text" name="password_confirmation" value="" class="form-control"> </div> <div class="col-sm-4"> 我就是一个提示 </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">邮箱:</label> <div class="col-sm-6"> <input type="text" name="email" value="{{old('email')}}" class="form-control"> </div> <div class="col-sm-4"> 我就是一个提示 </div> </div> </form> </div>
控制器
// 添加用户的处理 public function addSave(Request $request) { $input = $this->validate($request, [ // 表单的字段名 => 规则名 多个规则用 | 隔开 'username' => 'required|between:2,6', // 确认密码confirmed一定要写在原始密码上 'password' => 'required|confirmed', 'password_confirmation' => 'required', 'email' => 'required|email', ],[ // 表单字段名.规则名 => 你想输出的话 'username.required' => '用户名不能为空', 'username.between' => '用户名要在2-6位之间', 'password.required' => '密码必须填写', 'password.confirmed' => '确认密码不一致', 'password_confirmation.required' => '确认密码必须不能为空', 'email.required' => '邮箱不能为空', 'email.email' => '邮箱格式不正确', ]); dump($input); }
控制器第二种方案
class上面加
use Validator;
// 方案2 $validator = Validator::make($request->all(), [ // 表单的字段名 => 规则名 多个规则用 | 隔开 'username' => 'required|between:2,6', // 确认密码confirmed一定要写在原始密码上 'password' => 'required|confirmed', 'password_confirmation' => 'required', 'email' => 'required|email', ],[ // 表单字段名.规则名 => 你想输出的话 'username.required' => '用户名不能为空', 'username.between' => '用户名要在2-6位之间', 'password.required' => '密码必须填写', 'password.confirmed' => '确认密码不一致', 'password_confirmation.required' => '确认密码必须不能为空', 'email.required' => '邮箱不能为空', 'email.email' => '邮箱格式不正确', ]); # 打印出对象的所有方法 // dump(get_class_methods($validator)); // 如果有错返回true if ($validator->fails()) { return redirect()->back()->withErrors($validator); }
第三种方式
cmd中执行
php artisan make:request UserRequest
/http/Requests/UserRequest.php代码
public function rules() { return [ // 表单的字段名 => 规则名 多个规则用 | 隔开 'username' => 'required|between:2,6', // 确认密码confirmed一定要写在原始密码上 'password' => 'required|confirmed', 'password_confirmation' => 'required', 'email' => 'required|email', ]; } public function messages() { return [ // 表单字段名.规则名 => 你想输出的话 'username.required' => '用户名不能为空', 'username.between' => '用户名要在2-6位之间', 'password.required' => '密码必须填写', 'password.confirmed' => '确认密码不一致', 'password_confirmation.required' => '确认密码必须不能为空', 'email.required' => '邮箱不能为空', 'email.email' => '邮箱格式不正确', ]; }
控制器代码
// 引入自己的Request类 use App\Http\Requests\UserRequest; class UserController extends Controller { // 添加用户的处理 public function addSave(UserRequest $request) { dump($request); }
21、切换默认语言为中文
1、下载中文语言包 https://github.com/caouecs/Laravel-lang 2、压缩包中src文件夹中找出cn的语言 3、文件拷贝到项目,路径为resources\lang 4、修改配置文件config/app.php 'localt' => 'en' 改为 cn
22、 配置连接数据库信息
在laravel中修改连接数据库的文件有两处
修改 .env文件
修改 config/database.php文件
laravel5.4之后对我们数据库的编码进行了默认改变,默认使用utf8mb4 -- UTF-8 Unicode, 排序规则 utf8mb4_unicode_ci
方案一【推荐】 修改.env文件来连接数据库
通过配置后,发现如果我们的数据表有前缀,在.env中不能去设置。
给.env文件增加配置表前缀 在config\database.php文件中 'mysql'数组里增加 // 给.env文件中添加表前缀 'prefix' => env('DB_PREFIX', ''), 在.env文件中增加 la_可修改其他的 DB_PREFIX=la_
23、DB类执行原生SQL语句
要先引入类 use DB; // 添加操作 $ret = DB::insert('insert into test_member (name, age, email) values (:name, :age, :email)', [':name'=>'张三', ‘:age’=>20, ':email'=>'admin@admin.com']); // 修改操作 $ret = DB::update('update test_member set age=:age where id=:id', [':age'=>12, ':id'=>1]); // 查询select # 查询单条 $ret = DB:: selectOne('select * from web64_user where id=:id', ['id'=>$id]); # 查询多条 $ret = DB::select("select * from web64_user"); // 删除操作 $ret = DB::delete("delete from test_member where id=:id",[':id=>1']);
例子
/* // 添加 $sql = 'insert into la_users(username, password) values (:username,:password)'; // 返回true/false $ret = DB::insert($sql, [':username'=>'admin', ':password'=>'admin888']);*/ // 修改 /*$sql = "UPDATE la_users set username=:username where id=:id"; // 返回影响的行数 $ret = DB::update($sql, ['username'=>'张三','id'=>1]);*/ // 查询 // 查询单条 /*$sql = "SELECT * FROM la_users WHERE id=:id"; // 返回一个集合对象 $ret = DB::selectOne($sql, ['id'=>1]);*/ // 查询多条 /*$sql = 'select * from la_users'; $ret = DB::select($sql);*/ // 删除 $sql = 'delete from la_users where id=:id'; // 返回影响的行数 $ret = DB::delete($sql, ['id'=>1]); dump($ret);
24、DB构建器操作数据库
24.1 查询(get/first)
table(表名),这里的表名,如查有前缀不用写
# 查询多条get all
# all不可接 where
// 查询所有无条件 $data = DB::table('user')->get(); // 查询所有,并指定字段 推荐使用第一种方式 $data = DB::table('user')->get(['name', 'age']); // 获取ID大于5的数据 $ret = DB::table('member')->where('id','>=',5)->get(); // when 来进行条件的搜索 // 根据关键词来搜索 $kw = $request->get('kw'); /*$ret = DB::table('users')->when($kw, function(Builder $query)use($kw){ $query->where('username', 'like', "%{$kw}%"); })->get();*/ $ret = DB::table('users')->where(function(Builder $query)use($kw){ $query->where('username', 'like', "%{$kw}%"); })->get(); // 查询单条记录 $ret = DB::table('member')->where('id', 5)->first(); // 获取某个具体的值 $ret = DB::table('member')->where('id', 5)->value('name'); // 获取一列数据 $ret = DB::table('member')->pluk('name'); // 获取以id为下标name为值的一列数据 $ret = DB::table('member')->pluk('name','id'); // 排序操作 $ret = DB::table('member')->orderBy('id', 'desc')->get(); // in查询 $ret = DB::table('users')->whereIn('id',[2,3,5])->get(); // between $ret = DB::table('users')->whereBetween('id', [2,3,5])->get(); // like $ret = DB::table('users')->where('id','like','2%')->get(); // 分页获取数据 $ret = DB::table('users')->orderBy('id', 'desc')->offset(0)->limit(2)->get(); limit:表示限制输出的条数 offset:从什么地方开始,起始从0开始
24.2 添加
insert() 可以同时添加一条或多条,返回值是布尔类型 insertGetId() 只能添加一条数据,返回自增的id // 添加数据 $ret = DB::table('member')->insert([ 'name' => '张三丰', 'age' => 50, 'email' => 'ee@ee.com', ]); // 添加数据并得到插入时的ID值 $id = DB::table('member')->insertGetId([ 'name' => '张三丰', 'age' => 50, 'email' => 'ee@ee.com', ]); // 添加多条记录 $ret = DB::table('member')->insert([ [ 'name' => '张三丰', 'age' => 50, 'email' => 'ee@ee.com', ], [ 'name' => '张三丰', 'age' => 50, 'email' => 'ee@ee.com', ] ]);
24.3 修改数据
$ret = DB::table('member')->where('id', 2)->update([ 'name' => '修改一下', ‘age’ => 50 ]);
24.4 删除数据
$ret = DB::table('member')->where('id', 2)->delete();
25、工具
# cmd执行 composer require barryvdh/laravel-debugbar # config/app.php增加 暂不用 # Barryvdh\Debugbar\ServiceProvider::class,
# 执行命令添加配置文件
php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider"
26、创建模型
php artisan make:model [目录名/]模型文件名 # 分目录的 php artisan make:model Models/Member # 创建模板并生成迁移文件 实际工作中,就是创建模型同时就创建好迁移文件 php artisan make:model Models/Article -m -m 生成迁移文件
27、模型限制
27.1 定义表名
模型所对应的默认表名是模型类型的复数形式,如果表名不统一则需要指定一下。
// 指定表名 protected $table = 'member';
27.2 指定主键名
laravel中默认的主键ID名为id,如果你创建的表字段中主键ID的名称不为id,则需要通过$primaryKey来指定一下
// 指定主键名称 protected $primaryKey = 'mid';
27.3 指定时间戳($timestamps)
默认情况下,模型操作会认为在你的数据库表有created_at和updated_at字段。如果你不希望让模型来自动维护这两个字段,可在模型内将$timestamps属性设置未false
// 时间戳 这里一定要注意它是用 public public $timestamps false
27.4 批量赋值($fillable 与 $guarded)
当通过create方法来保存数据的时候,你需要先在你的模型上定义$fillable或$guarded属性
// 批量赋值 # 白名单 protected $fillable = ['允许添加的字段名']; #黑名单 protected $guarded = ['拒绝添加的字段名'];
28 DURD操作
28.1 添加数据 # 方法1 save() #对象属性方式 返回模型对象 # 方法2 insert() #数组方式 可以添加一条或多条 返回true/false # 方法3 create() # 数组方式 需要在模型中设置号fillable 或guarded属性 返回模型对象
例子:
// 添加 // 方案1 /*$model = new Article(); $model->uid = 1; $model->title = '我就是一条记录'; $model->cnt = '你好'; $model->save(); var_dump($model->id);*/ // 方案2 $data = [ 'uid' => 2, 'title' => 'php', 'cnt' => 'php是世界上最好的语言', ]; $data2 = [ [ 'uid' => 2, 'title' => 'php', 'cnt' => 'php是世界上最好的语言', ],[ 'uid' => 3, 'title' => 'php3', 'cnt' => 'php是世界上最好的语言3', ] ]; // 返回布尔类型 true/false dump(Article::insert($data)); dump(Article::insert($data2)); // 推荐写法 dump(Article::create($data));
29 查询
# 查询单条 first() # 查询多条 get() # 条件 where()
# 排序 orderBy() # 取指定的值 value() # 取指定的列 pluck() # 查询总记录数 count()
30 修改数据
# 方法一
save() # 对象属性方式 返回的是模型对象
# 方法2
update() # 数组 返回受影响行数
31 删除
# 删除 一定要指定条件删除
delete() #对象删除
destroy($id) # 静态方法删除 默认表字段主键名为ID,如果不是则需要模型中定义一下
例子
// 删除 1 $id = 1; $model = Article::find($id); dump($model->delete());*/ // 删除 2 dump(Article::destroy($id));
软删除
引入命名空间
use Illuminate\Database\Eloquent\SoftDeletes; 1、在表字段中要有deleted_at字段 可以在迁移文件中直接添加一个方法 $table->softDeletes cmd 中执行 php artisan migrate:refresh --seed
2、 // 在模型中引入trait use SoftDelete; // 指定删除的标识 protected $dates = [删除标识字段名deleted_at] // 只读取软删除的数据 $ret = Article::onlyTrashed()->get(); // 恢复软删除 $model = Article::withTrashed()->find(1); $model->restore();
32、faker来进行数据填充
32.1
laravel从5以后,默认已安装该扩展包
通过运行Artisan 命令make:seeder
来生成 Seeder。由框架生成的 seeders 都将被放置在 database/seeds
目录下:
php artisan make:seeder ArticleSeeder
代码:
<?php use Illuminate\Database\Seeder; // 引入文章模型 use App\Models\Article; class ArticleSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { // 清空数据表 //Article::truncate(); // 实例化 $faker = Faker\Factory::create(); for($i=1;$i<10;$i++){ $data = [ 'uid' => $i, 'title' => $faker->word, //'desn' => $faker->sentence, 'cnt' => $faker->text, ]; Article::create($data); } } }
cmd执行:
php artisan db:seed --class=ArticleSeeder
32.2
// 在database/factories里创建的
composer dumpautoload
php artisan make:factory ArticleFactory -m Models/Article
在修改创建的文件,代码如下:
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Models\Article; use Faker\Generator as Faker; $factory->define(Article::class, function (Faker $faker) { return [ 'uid' => rand(1,10), 'title' => $faker->word, 'desn' => $faker->sentence, 'cnt' => $faker->text, ]; });
修改database/seeds/ArticleSeeder.php
// 引入文章模型 use App\Models\Article; ... ... ... public function run() { // 调用数据工厂 factory(Article::class, 20)->create(); }
cmd执行:
php artisan db:seed --class=ArticleSeeder
33、增加监听类 模型事件 参考文章:https://blog.csdn.net/qq_33229176/article/details/80425311
php artisan make:observer ArticleObserver
34、数据分页
# 标准分页 Model::paginate(每页显示的记录数) # 简单分页 Model::simpleaPaginate(每页显示的记录数) # 模板 {{ $model->links() }} # 升级版: 这个分页后带参数 {{ $data->appends(request()->except('page'))->links() }}
控制器
public function index(Request $request) { // 关键词 $title = $request->get('title'); // 搜索条件 $data = Article::when($title, function(Builder $query) use ($title){ $query->where('title','like',"%{$title}%"); })->paginate(env('PAGESIZE')); return view('article.index', compact('data')); }
35、session处理
laravel中的session默认存到文件中
session文件的目录:storage\framework\sessions
session配置文件在config/session.php和.env也有,推荐修改.env
操作session的方法在laravel中有两种方案,有类来操作也有利用辅助函数来操作
35.1 session设置
// 写入session // 方法1 Session::put('键名','值');
// 方法2 辅助函数 session('键名'=》'值'); 注:辅助函数存储session的时候一定要以数组的形式来定义
35.2 读取操作
// 读取session // 方式1 Session类 dump(Session::get('键名',[默认值])); // 方式2 辅助函数 dump(session('session名称')); // 读取全部的session dump(Session::all()); dump(session()->all());
35.3 判断某个Session是否存在
// 方法一 dump(Session::has('session名称')); // 方法二 dump(session()->has('session名称'));
35.4
// 删除Session
// 方法一
Session::forget('session名称');
if (!Session::has('session名称')) { echo 'name1:已被删除'; } // 方法二 session()->forget('session名称'); if (!session()->has('session名称')) { echo 'name2:已被删除'; }
// 删除全部的session
// 方法一 Session::flush(); // 方法二 session()->flush();
36 闪存
使用这个方法保存sessoin,只能将数据保留到下个HTTP请求,然后就会被自动删除 // 方法一 Session::flash('msg', '你好世界'); // 方法二 session()->flash('msg', '你好世界'); dump(session('msg')); // with来设置闪存 return redirect()->route('session.index')->with('msg', '我是成功的'); // 模板中使用 {{ session(key) }} 来读取闪存
37 中间件
中间件作为请求和相应之间的中间人。它是一种过滤机制类型。
在laravel中通过中间件来进行后台用户是否登录的验证操作,防止后台用户FQ操作。
中间件可以通过执行以下命令来创建,所有的中间件都位于app/Http/Middleware目录。
php artisan make:middleware 中间件
37.1 注册中间件
在laravel有两种类型的中间件。即:【全局中间件】和【路由中间件】
全局中间件将在应用程序的每个HTTP请求运行,而路由中间件将被分配到一个指定的路由。
中间件可在app/Http/Kernel.php注册
该文件包含两个属性:$middleware和$routeMiddleware。$middleware属性用于注册全局中间件,$routeMiddleware属性用于注册路由指定中间件。
web.php 单个或者分组都可以 checkUser是中间件的别名
Route::group(['middleware'=>['checkUser']], function(){ Route::get('sess', 'SessController@index')->name('sess');//->middleware('checkUser'); });
Kernel.php
// 全局中间件 protected $middleware = [ \App\Http\Middleware\TrustProxies::class, \App\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, #\App\Http\Middleware\CheckUser::class, ]; // 路由中间件 protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, # 注册一个自己定义的路由中间件 'checkUser' => \App\Http\Middleware\CheckUser::class, ];
app\Http\Middleware\CheckUser.php
# 中间件 class CheckUser { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { // 在此我们编写业务代码 echo '111'; // 返回的是response对象 return $next($request); } }
可以在控制器增加中间件
app\Http\Controller\SessController.php
public function __construct() { return $this->middleware('checkUser')// 黑名单,过滤指定的控制器->except(['index']); }
38 验证码
我们通过 Composer 安装 Captcha 扩展包
composer require mews/captcha
配置
使用Captcha服务提供者之前还需要在config/app.php
中注册服务提供者:
'providers' => [ // ... Mews\Captcha\CaptchaServiceProvider::class, ]
同时注册下相应门面:
'aliases' => [ // ... 'Captcha' => Mews\Captcha\Facades\Captcha::class, ]
如果要使用自定义的配置,还可以发布配置文件到config
目录:
$ php artisan vendor:publish
编辑新生成的captcha.php
:
return [ 'default' => [ 'length' => 5, 'width' => 120, 'height' => 36, 'quality' => 90, ], // ... ];
点击更换验证码
<img id="vimg" src="{!! captcha_src('mini') !!}"> <a id="kanbuq" href="javascript:;">看不清,换一张</a> <script> $('#kanbuq').click(function(){ // 得到图片元素对象 let vimg = $('#vimg'); // 获取它的src属性值,并追加内容 let src = vimg.attr('src')+'&vt='+new Date().getTime(); // 把内容写入src属性中 vimg.attr('src',src); }); </script>
验证码规则的中文提示 方案一,了解
app\http\Requests\LoginRequest.php public function rules() { return [ 'username' => 'required', 'password' => 'required', 'code' => 'required|captcha' ]; }
resources\lang\cn\validation.php 约120行添加 'captcha' => ':attribute不正确。', 约180行添加 'code' => '验证码',
方案二 推荐
app\http\Requests\LoginRequest.php public function rules() { return [ 'username' => 'required', 'password' => 'required', 'code' => 'required|captcha' ];
app\http\Requests\LoginRequest.php public function messages() { return [ 'username.required' => '用户名不能为空', 'password.required' => '密码不能为空', 'code.required' => '验证码不能为空', 'code.captcha' => '验证码验证不通过', ]; }
37.2
模板中调用
常用方法
# 返回 {!! captcha_src() !!} # 返回img的html {!! captcha_img() !!}
38 缓存
缓存文件在config/cache.php config/database.php也可修改 推荐在.env中 CACHE_DRIVER 修改
设置缓存
use Cache; # 门面
# 添加 如果key不存在则添加成功,如果key存在则返回false Cache::add('key','value', $minutes); # 设置 不管key值是否存在,都可以设置成功 Cache::put('key', 'value', $minutes); # 设置永久缓存 Cache::forever('key', 'value');
获取缓存数据
$value = Cache::get('key'); $value = Cache::get('key', 'default'); $value = Cache::get('key', default); # 获取的同时并存储 $value = Cache::remember('users', $minutes, function () { return 'key 不存的时候返回的数据'; });
检查缓存项是否存在
# 检查缓存的key值是否存在,存在返回true,否则返回false
Cache::has('key');
删除缓存数据
# 先获取再删除 $value = Cache::pull('key'); # 删除单个 Cache::forget('key'); # 清除所有的缓存 Cache::flush();
工具使用:
文件- 设置 - 工具 - Command Line Tool Support - 右上角+号 - 选择Tool based on Symfony Console确定 - 第一行名字随意、选择phar or php script、 Path to script选择laravel项目中的artisan文件,确定 这样就完成设置了 打开方式: Tools(工具)- Run Command
39 缓存设置到redis中
第一步:安装laravel支持的redis扩展
composer require predis/predis
第二步:在.env文件中修改存储介质
CACHE_DRIVER=redis
REDIS_HOSE
REDIS_PASSWORD
REDIS_PORT
第三部:开启redis启动
40 文件上传 在larave里面实现文件的上传很简单的,不用引入第三方的类库,直接通过Request对象就可以获取到上传文件资源后进行保存 # 获取上传的文件 $_FILES[文件与表单名称] $file = $request->file('文件表单名称'); # 验证文件是否存在 $request->hasFile('文件表单名称'); # 获取上传文件的后缀 $request->file('文件表单名称')->getClientOriginalExtension(); # 将文件移动到服务器指定的位置 上传方式 1 $request->file('文件表单名称')->move(路径,文件名)
代码:
controller
class FileController extends Controller { // 上传的显示 public function index() { return view('file.index'); } // 上传的处理 public function up(Request $request) { // 判断文件是否有上传 //dump($request->hasFile('pic')); $pic = ''; if ($request->hasFile('pic')) { // 有文件上传了 $file = $request->file('pic'); // 得到文件的扩展名 clientExtension也是可以获取扩展名 $ext = $file->getClientOriginalExtension(); // 生成文件名 // public_path laravel帮我们得到了一个public指向的路径 $filename = time().'.'.$ext; $info = $file->move(public_path('uploads'), $filename); $pic = $info->getFilename(); $html = <<<html <script> parent.window.document.querySelector('#img').src="/uploads/{$pic}"; </script> html; return $html; } dump($pic); } }
html
<!doctype html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>文件上传</title> <style> body{ margin:0px; padding:0px; font-size: 14px; } .box{ width:800px; margin:10px auto; } </style> </head> <body> <div class="box"> <form target="uppic" method="post" action="{{ route('up') }}" enctype="multipart/form-data"> @csrf <p> <input type="file" name="pic"> </p> <p> <input type="submit" value="文件上传"> </p> </form> <img src="##" id="img" style="width:200px"> <iframe src="" frameborder="0" name="uppic"></iframe> </div> </body> </html>
修改配置文件,让上传支持大文件,修改php.ini文件
upload_max_filesize
post_max_size
40、 使用Auth类来进行登录验证
配置文件:config/auth.php
'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ],
Model:
// 使用user模型来继承 use Illuminate\Foundation\Auth\User as Authorization; class User extends Authorization { }
controller
// 类外面写引入Auth用户登陆验证门面 use Auth; // 方法里写 # 如果guard不写,则表示默认,web $user = auth()->guard('web')->attempt($request->only(['username', 'password']));
dump($user);
$user && dump(Auth::user());
41、关联模型
$this->hasOne(关联model,[关联model的外健], [本model的外健]); return $this->hasOne(Extuser::class, 'uid', 'id'); # 关联表中的外键名 user_id, 本表中的主键ID为id return $this->hasOne(Extuser:;class);
代码: user表和users_info表
controller
// 方法一 #$user = User::find(1); // 一对一模型 #$userinfo = $user->userinfo()->first(); // 简写,同上 #$userinfo = $user->userinfo; // 方法二 // 预加载 效率更高 $user = User::with('userinfo')->where('id',1)->first(); // 调用扩展表中的信息 dump($user->userinfo->body); dump($user);
userModel
/** * 用户基础表和扩展表是一对一关系 hasOne * */ public function userinfo() { // 关联关系 关联模型 外键 主键 return $this->hasOne(UsersInfo::class,'users_id', 'id'); // 简写 外键必须是 表名称_id 主键名必须是id return $this->hasOne(UsersInfo::class); }
42、一对多关系
models
// 一个用户对应文章 一对多关系 hasMany public function articles() { //return $this->hasMany('app\Models\Articles', 'user_id','id'); return $this->hasMany(Articles::class, 'user_id','id'); }
controller
$user = User::find(1); # $arts = $user->articles(); // 写条件 # $arts = $user->articles('id','>',1)->get(); $arts = User::with(['articles'=>function($query){ $query->where('id','>=',1); }])->where('id', 1)->first(); // 取文章列表 dump($arts->articles);
多对多
controller
// 多对多 $user = User::find(1); /* // 查询它的权限 $auths = $user->auths->toArray(); // 获取当前的路由别名 dump($request->route()->getName()); // 得到二维数组的指定字段 dump(array_column($auths, 'name'));*/ // 同步权限 $user->auths()->sync([1,2]);
userModel
// 多对多关系,beLongsToMany public function auths() { // 关联模型 中间表表名 没有前缀 本模型对应中间表中字段 关联模型对应中间表中的字段 return $this->belongsToMany(Auth::class, 'user_auth', 'user_id','auth_id'); }
authModel
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Auth extends Model { protected $table = 'auth'; public $timestamps = false; protected $guarded = []; }
43、创建函数文件库
编辑composer.json文件
# 比如增加functions.php文件, 在autoload增加files项 "autoload": { "files": ["functions.php"] }
# 介绍一下
psr-4是类的加载
修改后执行命令
composer dumpautoload
44、datatables
中文官网:http://www.datatables.club/
45 创建资源路由器加 -r
php artisan make:controller Admin/RoleController -r -m Models/Role
php artisan make:controller Admin/PermissionController -r -m Models/Permission
php artisan route:list