Laravel记录
先放laravel中国官方文档:https://laravel-china.org/docs/laravel/5.6
—————————— 安装laravel项目 —————————
1、使用composer search 查找最新的版本:
composer search laravel //查找laravel包
2、show一下找到的包:
composer show --all laravel/laravel
——等待下就显示了包信息了。
3、linux上切换到/var/www,并使用composer进行安装laravel包
composer create-project laravel/laravel --prefer-dist laravel "5.3.*" //指定安装5.3.*版本,不加则安装最新稳定版 composer create-project --prefer-dist laravel/laravel laravel //安装最新稳定版
4、查看laravel版本:
在项目目录执行以下:
php artisan --version
——以上,安装完成了。
—————————— 路由和MVC —————————
// 路由(在目录:routes之下配置):
请求类型:get / post / put / patch / delete
1、基本路由:
1、get路由 // 访问domain,指向welcome模板 Route::get('/', function () { return view('welcome'); }); 2、post路由 // 访问domain/post,指向hello模板,不能通过url访问 Route::get('/post', function () { return view('hello'); }); // 3、 混合路由,get和post都可以。访问[域名/test]即可请求 Route::match(['get','post'], 'test', function () { return '哈哈哈哈哈'; }); // 4、任意路由,所有请求方式都可以。[域名/hello]即可访问 Route::any('/hello',function(){ return "Hello Laravel!"; });
// 路由中输出模板:
Route::get('/', function () {
return view('welcome');
});
// 路由关联控制器
Route::get('/member/info','MemberController@info');
// 路由群组:
Route::group(['prefix'=>'member'],function (){
// 路由1:访问[域名/member/user],返回1
Route::get('user',['as'=>'center',function(){
return '1';
}]);
// 路由1:访问[域名/member/sss/image],返回2
Route::get('sss/image',['as'=>'center',function(){
return '2';
}]);
});
//路由参数:
// 每次都得传参 Route::get('user/{id}', function ($id) { return '参数是:'.$id; }); // 后面加?可以不传参 Route::get('user/{id?}/{name?}', function ($id = null,$name = null) { return '参数是:'.$id; }); // 对参数id进行正则验证,错误的话就报错 Route::get('user/{id?}/{name?}', function ($id = null,$name='') { return '参数是:'.$id; })->where(['id'=>'[0-9]+','name'=>'[a-zA-Z]+']);
// 路由别名:
- 意义:当美化路由后,模板或者php代码不需要修改。
Route::get('user/center',['as'=>'center',function(){ return route('center'); //当改变user/center为user/person_center后,对应的模板文件中的名字不修改进行修改
}]);
// 资源路由:
Route::resource('users', 'UsersController');
相当于 =>
// 获取列表 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');
———————— 控制器 ————————
// 怎样新建一个控制器
—— 控制器位置:在app/Http/Controllers下
//路由关联该控制器:
Route::get('member/info','MemberController@memberInfo'); //方法1 Route::get('member/info',['uses' => 'MemberController@info']); //方法2
// 关联后,路由的特性怎么用
——若带参数,则直接在控制器处传参即可。如下:
1、路由绑定控制器,路由传参
Route::get('member/{$id}','MemberController@memberInfo');
2、控制器接收参数:
<?php
namespace App\Http\Controllers;
class MemberController extends Controller
{
public function info($id)
{
return '传进来的id是:'.$id;
}
}
——post同理
———————— 视图 ——————————
// 视图位置:
在resources/views之下
// 怎样新建视图
1、第一种: info.php 2、第二种: info.blade.php
// 怎样输出视图
return view('info'); //view之下的info模板文件 return view('member/info'); //view之下的member/info文件 //带参数,模板里面使用{{$age}}进行变量展示 return view('member/info',[ 'name' => 'Raven', 'age' => '23' ]);
———————— 数据库与数据表 ————————
//设置数据库,需要配置以下两个文件:
1、config/database.php //配置mysql的字符集和排序规则(utf8和utf8_general_ci)
2、.evn //设置数据库、账号、密码
请注意:原生/查询构造器,都得使用:
use Illuminate\Support\Facades\DB;
第一种:使用DB facade(原始查询方式)实现CURD ——(数据可以使用dump方法输出,比较好看):
1、添加需要使用的依赖 use Illuminate\Support\Facades\DB; 2、增 - 成功返回true $bool = DB::insert('insert into student(name,age) values (?,?)' , ['linfeng' , 19]); 3、修改 - 成功返回1 $num = DB::update('update student set age = ? where name = ?', [19, 'canzhu']); 4、查询 - 成功返回查询的数据 $students = DB::select('SELECT * FROM student where id > 1'); 5、删除 - 返回删除的总行数 $num = DB::delete('delete from student where id < ?' , [2]); //?是占位符,在数组里面设置值
第二种:查询构造器 - 方便操作,减少风险
1、增加数据
// 增 - 成功返回true $bool = DB::table('student')->insert([ 'name' => 'linfeng', 'age' => '22', ]); // 增 - 返回主键ID $id = DB::table('student')->insertGetId([ 'name' => 'linfeng', 'age' => '22', ]); // 增多条数据 $bool = DB::table('student')->insert([ ['name' => 'linfeng', 'age' => '22'], ['name' => 'ccc', 'age' => '33'], ['name' => 'fff', 'age' => '55'], ]);
2、更新数据:
// 更新数据 - 返回受影响的行数 $bool = DB::table('student')->where(['id'=>2])->update([ 'age' => 14, ]); // 自增1,不加where则全部多自增1 $bool = DB::table('student')->increment('age'); // 自增3,不加where则全部多自增1 $bool = DB::table('student')->increment('age',3); // id为2的age自增3 $bool = DB::table('student')->where(['id'=>2])->increment('age',3); // 自减1 $bool = DB::table('student')->where(['id'=>2])->increment('age');
3、删除
// 返回删除的行数 DB::table('student')->where(['id'=>10]); // 删除条件 DB::table('student')->where('id','>=', 7); // 清空数据表,主键id从1开始 DB::table('student')->truncate();
4、查询数据:
// 1、get() - 查询数据 $students = DB::table('student')->get(); // 2、first() - 查询单条数据 $students = DB::table('student')->orderBy('id','desc')->first(); // 3、where() - 查找id>3的 $students = DB::table('student')->where('id','>',3)->get(); // 查找id>3 并且age>30的 $students = DB::table('student')->whereRaw('id > ? and age > ?', [3, 30])->get(); //4、pluck - 查询单个字段,并可以指定下标(以下id为下标) $students = DB::table('student')->whereRaw('id > 3 and age > 30')->pluck('name','id'); //5、select() - 查询多个字段 $students = DB::table('student')->whereRaw('id > 3 and age > 30')->select('name','age')->get(); //6、chunk() - 分批查询 DB::table('student')->chunk(2,function ($students){ // 本例子的2表示每次查两条,一般每次查个1000条之类的。 // 对每次查出来的$students进行处理 });
// 聚合函数:
1、count() $num = DB::table('student')->count(); 2、max() $ageMax = DB::table('student')->max('age'); //查找年纪最大的 3、min() 4、avg() 5、sum()
————————数据库操作之:Eloquent ORM————————
// ORM简介、模型建立和查询数据
1、ORM简介:
数据表对应Model,进行数据库交互
2、创建模型:
php artisan make:model Student
你也可以直接在app目录之下创建Student.php文件,注意命名空间、继承model和use Illuminate\Database\Eloquent\Model;
3、数据库交互:
首先创建模型Student.php:———不含任何的方法。
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Student extends Model { // 指定表名。以下关联了student表 protected $table = 'student'; // 指定主键(默认为id,如果主键不是id则需要指定,我这里其实是不需要指定的。) protected $primaryKey = 'id'; }
控制器使用模型:
// 0、先 use App\Student; // 1、查找所有数据 - all() $students = Student::all(); // 2、通过主键查找数据 $students = Student::find(2);
// 查询构造器在ORM中的使用:
$students = Student::count(); // 其他查询构造器也是类似的,直接把语法写在后面即可。
//关于自动维护时间戳 - created_at和updated_at
1、插入的时候,默认是timestamp格式,你有在模型添加以下函数,则会自动变成时间戳存入数据库。
// 把时间按照【时间戳格式】存起来,默认是【时间格式】 public function getDateFormat(){ return time(); }
2、取出时间的时候,默认是timestamp格式的,你有在模型添加以下函数,则会自动变成时间戳存入数据库。
// 按照【时间戳格式】取出数据。默认是【时间格式】 public function asDateTime($val){ return $val; }
————当然了,你也可以自己进行转换。
// 新增数据 - save和create:
1、save - 单条数据添加 $students = new Student(); $students = $students::find(10); $students->name = 'linfeng'; $students->age = 23; $bool = $students->save(); 2、create - 批量赋值 $students = Student::create( ['name' => 'linfeng', 'age' => 100] ); ——批量赋值需要在模型层设置—— // 指定允许批量赋值的字段name和age protected $fillable = ['name', 'age'];
// 查找或新增 firstOrCreate (如果没有则新增,这个还是挺重要的。)
$student = Student::firstOrCreate([ 'name' => 'ddd' ]);
// 查找或创建实例 - firstOrNew (如果数据库没有该数据,则创建一个对象,此时对象还没有插入数据库,可以直接save就可以保存)
$student = Student::firstOrNew([ 'name' => 'dddss' ]); $student->save();
// 使用ORM修改数据
1、通过模型更新
// save方法会自动更新时间戳 $student = Student::find(12); $student->age = '12'; $bool = $student->save();
2、结合查询语句,批量更新
$num = Student::where('id', '>', 5)->update([ 'age' => 100 ]);
// 使用ORM删除数据
1、根据模型删除 - delete();
$student = Student::find(8); $bool = $student->delete();
2、根据主键删除 - destory
$num = Student::destroy(2,3,8);
3、指定条件删除
$num = Student::where('id','>6')->delete();
模型例子:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Student extends Model { // 指定表名。以下关联了student表 protected $table = 'student'; // 指定主键(默认为id,如果主键不是id则需要指定,我这里其实是不需要指定的。) protected $primaryKey = 'id'; // 开启自动维护时间戳 public $timestamps = true; // 指定【允许批量赋值】的字段name和age protected $fillable = ['name', 'age']; // 指定【不允许批量赋值】的字段name和age protected $guarded = ['name', 'age']; // 把时间按照【时间戳格式】存起来,默认是【时间格式】 public function getDateFormat() { return time(); } }
———————— 模板 ————————
//模板文件的资源文件使用:
// asset()方法用于引入 CSS/JavaScript/images 等文件,文件必须存放在public文件目录下。 <a href="{{asset('css/app.css')}}"></a>
1、 介绍和模板继承
blade模板会被编译成php代码并缓存起来(修改时候会重新编译),不限制你在模板文件中使用原声php代码
模板继承-主模板:
// 1、模板(layout)使用[@section('header') @show]这两个标签包住内容。如下: <div class="header"> @section('header') 头部 @show </div> // 2、使用yield进行 <div class="main"> @yield('content','主要区域内容') </div>
子模板继承和使用:
@extends('layouts') @section('header') 这里可以重写你的内容 @stop @section('content') 这里可以重写你的内容 @stop
————这里需要讲一下@section和@yeild的区别。
@section:子模板有定义新内容,父模板的内容仍然可以存在。添加@parent即可。可以用作拓展。
@yeild:子模板有定义内容,则父模板内容覆盖。
2、基础语法和include使用:
// 1、输出php变量 {{$variable}} // 2、原样输出 @{{$variable}} // 此时输出的就是{{$variable}},不是变量 // 3、模板中的注释: {{-- 本注释在网页上查看源代码也是看不到的 --}}
include引入子视图:
@include('student.test')
3、流程控制
// 1、if: @if($name == 'aaa') aaa @elseif($name == 'bbb') bbb @else ccc @endif // 2、unless @unless($name == '') unless是if的取反 @endunless // 3、for @for($i = 0; $i < 10; $i++) <p>{{ $i }}</p> @endfor // 4、foreach @foreach($students as $student) <p>{$student->name}</p> @endforeach // 5、forelse @forelse($students as $student) <p>{$student->name}</p> @empty <p>暂时没有数据哦</p> @endforelse
4、模板中的url
// 1、url() - 路由名称 <a href="{{url('student/test')}}"></a> // 2、route() - 通过路由的别名生成url <a href="{{route('test')}}"></a> // 3、action() - 指定控制器和方法名 <a href="{{action('StudentController@test')}}"></a>
———————— 请求 ————————
laravel中使用的请求组件为:symfony/http-foundation
// 获取类型、获取是否要的类型:
// 获取某个参数 if($request->has('name')){ echo $request->input('name'); } // 获取所有参数,包含了url的后缀 $request->all() // 判断请求类型 $request->method() // 判断是否GET请求 $request->isMethod('GET') // 返回true或者false $request->ajax() // 获取url dd($request->url()); // 只获取某些值 $input = $request->only(['username', 'password']); // 排除某些值 $input = $request->except(['credit_card']);
// session - 默认配置在config/session.php中
// 1、request进行session操作 $request->session()->put('key1','value1'); echo $request->session()->get('key1'); // 2、辅助函数: session()->put('key2','value2'); echo session()->get('key2'); // 3、session类: use Illuminate\Support\Facades\Session; //需要使用到这个类 Session::put('key3','value4'); echo Session::get('key3'); // 4、批量存session - 数组的方式 Session::put([ 'key3'=>'value4', 'key4'=>'value5', ]); echo Session::get('key4'); // 5、把数据存到session数组中 - 以下name是个数组 Session::push('name','linfeng'); Session::push('name','chencanzhu'); dd(Session::get('name')); // 6、取数session并删除数据 Session::pull('name'); // 7、取出所有session数据 Session::all(); // 8、判断是否存在该session值 Session::has('name'); // 9、删除指定ssession值 Session::forget('name'); // 10、清空所有session数据 Session::flush(); // 11、暂存session数据 - 只有第一次访问存在,第二次就不存在了。 Session::flash('key-flash','value-flash');
// 响应
// 1、字符串 return '222'; // 2、视图 return view('test'); // 3、json return response()->json(['a' => '1', 'b' => '2']); // 4、重定向 return redirect('test2'); return redirect()->back();
———————— middleware(中间件) ————————
作用:过滤HTTP请求
例子:以下实现的是,在访问activity1和activity2之前,都需要判断时间到了没有,没有则跳回指定界面。
1、创建中间件:在app\Http\Middleware\写一个中间件Activity.php,如果时间没到,则跳回activity0
use Closure; public function handle($request, Closure $next) { if (time() < strtotime('2018-03-03')) { return redirect('activity0'); } return $next($request); }
——中间件包含的路由在被访问前,都会先检测中间件。
2、注册中间件:在app\Http\Kernel.php的$routeMiddleware数组加入:
'activity' => \App\Http\Middleware\Activity::class,
3、使用中间件:在路由处:
Route::group(['middleware' => ['activity']],function (){ Route::any('activity1','activityController@activity1'); Route::any('activity2','activityController@activity2'); });
———————— CSRF保护 ————————
// 表单中使用
<form method="POST" action="/profile"> @csrf ... </form>
// ajax中使用
// 添加meta <meta name="csrf-token" content="{{ csrf_token() }}"> // 将信息添加到JQ的所有请求头 $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
// 排除指定 URL 不做 CSRF 安全校验
有时候我们需要从 CSRF 保护中间件中排除一些 URL,例如,如果你使用了第三方支付系统(如支付宝或微信支付)来处理支付并用到他们提供的回调功能,这时候就需要从 Laravel 的 CSRF 保护中间件中排除回调处理器路由,因为第三方支付系统并不知道要传什么 token 值给我们定义的路由。
通常我们需要将这种类型的路由放到文件 routes/web.php
之外,比如 routes/api.php
。不过,如果必须要加到 routes/web.php
中的话,你也可以在 app/Http/Middleware/VerifyCsrfToken.php
中间件中将要排除的 URL 添加到 $except
属性数组:
<?php namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; class VerifyCsrfToken extends Middleware { protected $addHttpCookie = true; /** * The URIs that should be excluded from CSRF verification. * 以下加入不需要 csrf 验证的路由 * @var array */ protected $except = [ 'backend/login/', 'backend/login/login_check', 'alipay/*', ]; }
———————— 表单 ————————
// 分页:
1、控制器处: $students = Student::paginate(10); 2、模板处 {{$students->link()}}
// 在表单中伪造 delete 等其他请求:
// 其实真正的请求类型是 delete
<form action="/task/1" method="POST"> <input type="hidden" name="_method" value="DELETE"> </form>
—————— 验证类 - validator ——————
// 第一种:自动验证,错误会自动抛出异常。和跳转(表单提交情况下)。
validate类验证 - get或者post提交的方式:
public function query(Request $request){ $this->validate($request, [ 'name' => 'required|max:255', 'sex' => 'required|integer', 'age' => 'required|integer', ],[ // 规则提示可读性 'integer' => ':attribute 必须为整数', 'required' => ':attribute 为必填项', ],[ // 字段提示转为汉字 'name' => '姓名', 'sex' => '性别', 'age' => '年龄', ]);
// 验证通过,继续代码...,请注意。此时如果没有通过,会自动抛出422异常。 }
1)表单提交情况下,验证不通过,会重定向到上一个界面,并产生一个对象$errors,在上一个界面能获取到错误。
// 1、取出所有错误 @if(count($errors)) @foreach($errors->all() as $error) <li>{{ $error }}</li> @endforeach @endif // 2、取出第一条错误信息 @if(count($errors)) <p>{{ $errors->first() }}</p> @endif
2)AJAX 提交情况下:—— 直接抛出错误,并附带错误信息
如果是 AJAX 请求,带 422 状态码的 HTTP 响应将会返回给用户,该响应数据中还包含了 JSON 格式的验证错误信息。
// 第二种:手动创建验证器
use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Validator; /** * 登录信息监测 * */ public function loginCheck(Request $request){ $validator = Validator::make($request->all(), [ 'admin_username' => 'required', 'admin_password' => 'required', 'captcha' => 'bail|required|captcha', ]); $errors = $validator->errors(); //错误 $errorsAll = $errors->all(); // 返回所有错误 $hasAdmin = $errors->has('admin_username'); //查看admin_username是否验证不通过
//然后开始写逻辑,if($hasAdmin){return '用户名必须填写'}
... }
—— 获取更多的信息和更多验证规则请查看:https://laravel-china.org/docs/laravel/5.7/validation/2262#rule-accepted
———————— 用户认证 ————————
// 生成Auth文件
php artisan make:auth
执行后自动生成了:
1、Home控制器,视图auth、layouts模块、home.blade.php文件,路由也自己增加了:
Route::get('/home', 'HomeController@index')->name('home');
// 数据迁移 - 登录服务器,在laravel项目下执行:
php artisan migrate
会发现数据库多了三张表:migrations、password_resets、users
——为什么要登录服务器,因为我的代码是放在服务器上的啊。在本地执行就创建本地的表了。
// 创建数据迁移文件: -- 这个对我没什么用,直接导入数据库即可。
// 1、命令生成 php artisan make:migration create_students_table --create=students // 2、新建模型的时候生成,加上-m参数即可 php artisan make:model Article -m
—— 然后把表里面有的字段进行增加即可。
———————— migration学习 ——————
是什么:我们可以使用其他工具建表建库,但是laravel提供了migration,相当于把所有的数据库操作都记了下来。别人就可以直接使用文件进行迁移了。
1、执行创建命令,则会在databases/migration下生成2018_08_08_create_users_table文件
php artisan make:migration create_users_table
2、在2018_08_08_create_users_table文件中的up函数(创建)进行添加你想要的字段:
public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('username',20); // 设置varchar长度20 $table->string('airline'); $table->timestamps(); }); }
3、执行迁移:
php artisan migrate --force
4、回滚迁移:
php artisan migrate:rollback // 回滚最近一次迁移
php artisan migrate:rollback --step=5 // 回滚最近的5次迁移
php artisan migrate:reset // 回滚所有的迁移
———————— 文件上传 ————————
1、在config/filesystems.php的disks添加项:
// 创建存储空间,把图片上传到这里 'uploads' => [ 'driver' => 'local', 'root' => public_path('uploads'), ],
2、控制器:
public function upload(Request $request) { if ($request->isMethod('POST')) { // 获取文件 $file = $request->file['filename']; //文件是否上传成功 if ($file->isValid()) { // 原文件名 $originalName = $file->getClientOriginalName(); // 拓展名 $ext = $file->getClientOriginalExtension(); // 文件类型mineType $type = $file->getClientMineType(); // 临时绝对路径 $realPath = $file->getRealPath(); // 重命名文件名 $fileName = date('Y-m-d-H-i-s').'-'.uniqid().'.'.$ext; $bool = Storage::disk('uploads')->put($fileName,file_get_contents($realPath)); } } }
———————— 邮件发送 ————————
// 配置
1、congif/mail.php
2、.evn文件需要配置
3、发送邮件:
// 1、引入Mail类 use Mail; // 2、编写发送邮件的方法 public function mail() { Mail::raw('邮件内容',function ($message){ $message->from('json_vip@163.com','慕课网'); $message->subject('邮件主题'); $message->to('349017128@qq.com'); }); }
———————— 缓存 ————————
// 设置和取出
// 0、声明使用Cache use Illuminate\Support\Facades\Cache; // 1、设置: Cache::put('key1','value1',120); //120是分钟 Cache::add('key1','value1',120); //与上同 Cache::forever('key1','value1'); //永久Cache // 2、取出 Cache::get('key1'); //取出 Cache::get('key1'); //取出后就删除了该数据 // 3、判断是否存在 Cache::has('key1'); //120是分钟 // 4、删除缓存 Cache::forget('key1'); //取出后就删除了该数据
———————— 错误与日志 ————————
// DEBUG模式
位置:config/app.php里面:
'debug' => env('APP_DEBUG', false),
我们发现设置是在.env文件下,所以打开.env文件,设置为true
APP_DEBUG=true
// HTTP日常
比如404、401、500错误,这些界面可以自定义。统一跳转到该界面
// 日志
config/logging.php里面设置
使用日志:
// 1、声明 use Illuminate\Support\Facades\Log; // 2、使用 Log::info('这是一个info级别的日志记录'); Log::error('这是一个error级别的日志记录')
———————— 队列 ————————
允许推迟耗时任务,从而提高web请求速度。
配置文件:config/queue.php
———————— artisan的基本使用 ————————
// 查看artisan可用的命令: php artisan 或php artisan list // 创建控制器: php artisan make:controller Index/TestController php artisan make:controller Index/TestController --resource // 绑定路由 Route::resource('/index/test','Index\TestController'); Route::get('/index/test','Index\TestController@index'); // 创建模型: php artisan make:model Models/Student php artisan make:model Models/Student --migration // 创建中间件 php artisan make:middleware Activity
———————— 拓展包 ————————
【验证码】
https://laravel-china.org/topics/2895/extension-recommended-mewscaptcha-image-authentication-code-solution
———————— 其他 ————————
// 设置时区
修改config/app.php的 timezone,原来为UTC,修改为:
'timezone' => 'Asia/Shanghai',
// 调试输出:
dd($res->toArray());
————占位符