1、 路由
大多数的应用构建都是以routes/web.php文件定义的路由开始的。
以访问StudentController.php的index方法为例
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class StudentController extends Controller
{
public function index($id=1){
return 'id为'.$id;
}
}
web路由配置
(1)基础路由
Route::get('/', function () {
return view('welcome');
});
//http://ip.com/laravel/public/index.php/test/post
Route::post('test/post',function(){
return '通过post访问';
});
(2)多请求路由
Route::any('student/any/{id}','StudentController@index');
//http://ip.com/laravel/public/index.php/multy1/4
Route::match(['get','post'],'multy1/{id?}','StudentController@index');
(3)路由带参
路由参数通常放在{}中,如果希望这个参数是可选的,就在参数后面加个?标记,前提是确保路由相应的变量有默认值
//id为必填,name可选
Route::get('user/{id}/{name?}',function($id,$name='im'){
return 'id-'.$id.'==name-'.$name;
});
(4)正则表达式约束
Route::get('user/{id}', function ($id) {})->where('id', '[0-9]+');
Route::get('user/{id}/{name}', function ($id, $name) {})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
(5)路由别名
路由别名:可以用as关键字或者name()指定别名,用route()利用别名生成别名对应的url地址
Route::get('student/index',['as'=>'stu',function(){
return route('stu');
}]);
Route::get('student/index',['as'=>'index','uses'=>'StudentController@index']);
Route::get('student/index', 'StudentController@index')->name('index');
//
public function index($id=1){
return route('index');
}
(6)路由群组
路由组允许你在大量路由之间共享路由属性,例如中间件或命名空间,而不需要为每个路由单独定义这些属性。共享属性应该以数组的形式传入 Route::group 方法的第一个参数中
// http://ip.com/my/test1 http://ip.com/my/test2
Route::group(['prefix'=>'my'],function(){
Route::get('test1',function(){
return 'test1';
});
Route::get('test2',function(){
return 'test2';
});
});
2、 控制器
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class StudentController extends Controller
{
public function index(){
return 123;
}
}
路由与控制器关联2种方法
//方法1
Route::get('index',[
'uses'=>'StudentController@index',
'as'=>'test'
]);
//方法2
Route::get('index','StudentController@index');
3、视图
视图文件一般存放于 resources/views 目录下。
例:
(1)在resources/views/student 新建index.blade.php文件
我是{{$name}}
(2)控制器
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class StudentController extends Controller
{
public function index(){
//方式1
//return view('student/index',['name'=>'im']);
//方式2
return view('student.index',['name'=>'im']);
}
}
(3)路由
Route::get('student/index','StudentController@index');
(4)访问
http://ip.com/laravel/public/index.php/student/index
4、模型关联
5、数据库
Laravel提供原生sql、查询构造器、Eloquent ORM 3种数据库操作方式
(1)原生sql
$student=DB::select('select * from students');//array()
$bool=DB::insert('insert into students(name,age) values(?,?)',['tom',23]);//bool(true)
$num=DB::update('update students set name=? where id=?',['ii',1]);//int(1)
$num=DB::delete('delete from students where id=?',[3]);//int(1)
(2)查询构造器
Laravel 的数据库查询构造器为创建和运行数据库查询提供了一个方便的接口。Laravel 的查询构造器使用 PDO 参数绑定来保护您的应用程序免受 SQL 注入攻击。
①增加
$bool= DB::table('students')->insert([
['name'=>'a','age'=>'20'],
['name'=>'b','age'=>'21']
]);
//如果数据表有自增 ID ,使用 insertGetId 方法来插入记录并返回 ID 值
$id = DB::table('students')->insertGetId(
['name' => 'john', 'age' => 25]
);
②修改
$num = DB::table('students')->where('id', 1)->update(['age' => 21]);
③删除
DB::table('students')->delete();
DB::table('students')->where('age', '<', 100)->delete();
DB::table('students')->truncate();
④查询
//table():为给定的表提供一个查询构造器实例
//select():查询指定列
//distinct():返回结果不重复
//get():获取结果
$students=DB::table('students')->select('id','name as fullname')->distinct()->get();
foreach ($students as $stu){
//你可以访问字段作为对象的属性来访问每列的值
echo $stu->id.'--'.$stu->fullname;
}
//first():只获取一行数据
$students=DB::table('students')->first();
echo $students->name;
//value():只返回某行某个字段的值
$name=DB::table('students')->where('id','1')->value('name');
echo $name;
//pluck():获取某一列值得集合,id为自定义键名
$names=DB::table('students')->pluck('name','id');
foreach ($names as $name) {
echo $name;
}
//chunk():分块查询,该方法一次获取结果集的一小块,并将其传递给闭包函数进行处理
DB::table('students')->orderBy('id','desc')->chunk(2, function ($students) {
foreach($students as $stu){
echo $stu->name;
}
//终止继续获取分块结果
// return false;
});
//chunkById():分块更新
/*如果要在分块结果时更新数据库记录,则块结果可能会和预计的返回结果不一致。
因此,在分块更新记录时,最好使用 chunkById 方法。 此方法将根据记录的主键自动对结果进行分页*/
DB::table('students')->where('age','<','21')->chunkById(2,function($students){
foreach($students as $stu){
DB::table('students')->where('id',$stu->id)->update(['age'=>18]);
}
});
//聚合函数
$count=DB::table('students')->count();
$max_age=DB::table('students')->max('age');
$avg_age=DB::table('students')->where('age','>','18')->avg('age');
//判断记录是否存在
$bool= DB::table('students')->where('age','>','100')->exists();
$bool= DB::table('students')->where('age','>','100')->doesntExist();
//addSelect():已经有了查询构造器实例,并且希望在现有的查询语句中加入一个字段
$query=DB::table('students')->select('id');
$students=$query->addSelect('name')->get();
foreach ($students as $stu){
echo $stu->id.'-'.$stu->name;
}
//DB::raw 在查询中使用原生表达式
$students=DB::table('students')->select(DB::raw("count('id') as count"))->first();
//selectRaw 方法可以代替 select(DB::raw(...))
$students=DB::table('students')->selectRaw("count('id')")->first();
//join():内连
DB::table('students')->join('subject','students.id','=','subject.stu_id')->get();
//leftJoin():左外连
DB::table('students')->leftJoin('subject','students.id','=','subject.stu_id')->get();
//rightJoin():右外连
DB::table('students')->rightJoin('subject','students.id','=','subject.stu_id')->get();
//crossJoin():交叉连接
DB::table('students')->crossJoin('subject')->get();
//group by /having
$users = DB::table('users')
->groupBy('account_id')
->having('account_id', '>', 100)
->get();
(3)Eloquent ORM
class Student extends Model
{
//重定义表:默认情况下表是模型类名的复数
protected $table="student";
//重定义主键:默认主键是id
protected $primaryKey='stuid';
//可操作字段
protected $fillable=['title','content'];
//如果希望使用非自增和非数字的主键则需要定义为false;
public $incrementing = false;
//主动递增id的类型:如果递增的主键不是一个整数
protected $keyType='string';
//不想让Eloquent自动管理created_at和updated_at这两列
public $timestamps=false;
//自定义存储时间戳的字段名,可以在模型中设置 CREATED_AT 和 UPDATED_AT 常量的值来实现
const CREATED_AT = 'create_time';
const UPDATED_AT = 'update_time';
//自定义时间戳格式1:决定日期属性在数据库的存储方式
protected $dateFormat='Y-m-d';
//自定义时间戳格式2
public function getDateFormat(){
return time();
}
//禁止系统自动转换created_at和updated_at两个字段时间格式
public function asDateTime($value){
return $value;
}
}
①增加
public function index(){
//save可以保存也可以更新
$student=new Student();
$student->name='xiao';
$student->age=23;
$student->save();
}
批量赋值:可以使用 create 方法来保存新模型,此方法会返回模型实例。不过需要在模型上指定 fillable 或 guarded 属性,因为所有的 Eloquent 模型都默认不可进行批量赋值。
StudentController.php
public function index(){
//批量赋值
$student=Student::create(['name'=>'111','age'=>11]);
}
Student.php模型类
class Student extends Model{
//$fillable批量赋值的白名单,$guarded与之相反是黑名单,两者只能选一个
protected $fillable=['name','age'];
}
②修改
//更新
$student=Student::find(3);
$student->name='小小';
$student->save();
//批量更新
$num=Student::where('id','<',3)->update(['age'=>25]);
③删除
//delete()
$student = Student::find(19);
$student->delete();
//destroy():如果知道模型的主键,可以直接使用destroy方法来删除模型,而不用先去数据库中查找
Student::destroy(1,2,3)
//通过查询删除模型
Student::where('id','>', 1)->delete()
④查询
Eloquent模型也是查询构造器,所以可以使用查询构造器可用的所有方法。
<?php
namespace App\Http\Controllers;
use App\Student;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class StudentController extends Controller
{
public function index()
{
$students=Student::all();
$student=Student::find(1);
$students=Student::where('age','>','18')//添加查询条件
->orderBy('id','desc')
->get();//然后使用get方法,get()前面不加约束与all()相同
}
}
6、 Artisan基本用法
(1)查看所有可用的Artisan命令(两种)
root@ubuntu:/var/www/html/laravel# php artisan
root@ubuntu:/var/www/html/laravel# php artisan list
(2)查看migrate命令帮助信息
root@ubuntu:/var/www/html/laravel# php artisan help migrate
(3)创建StudentController控制器
root@ubuntu:/var/www/html/laravel# php artisan make:controller StudentController
(4)创建Student模型
root@ubuntu:/var/www/html/laravel# php artisan make:model Student
(5)创建Activity中间件
root@ubuntu:/var/www/html/laravel# php artisan make:middleware Activity
7、数据迁移
使用artisan命令 make:migration,新创建的迁移会放在你的database/migrations 目录
–table 和 --create 选项也可用于确定表的名称以及是否在迁移中创建新的数据表
如果你想自定义生成迁移文件的个人存放路径,你可以在你执行 make:migration 命令行的时候使用 --path 选项
(1)新建迁移文件有2种方式
① 新建一个student表的迁移文件
root@ubuntu:/var/www/html/laravel# php artisan make:migration create_students_table
②生成Student 模型的同时新建迁移文件
root@ubuntu:/var/www/html/laravel# php artisan make:model Student -m
(2)打开步骤①新建的迁移文件 /database/migrations/2019_12_30_073608_create_students_table.php,在up()方法补充其他字段,up 方法是用于新增数据库的数据表、字段或者索引的,而 down 方法应该与 up 方法的执行操作相反。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateStudentsTable extends Migration
{
public function up()
{
Schema::create('students', function (Blueprint $table) {
$table->bigIncrements('id');//id 自增字段
$table->string('name');//name varchar
$table->integer('age')->unsigned()->default(0);//age int,默认值为0,非负数
$table->integer('sex')->unsigned()->default(1);//sex int,默认值为1, 1男 2女 3未知
$table->integer('created_at')->default(0);//created_at int
$table->integer('update_at')->default(0);//update_at int
});
}
public function down()
{
Schema::dropIfExists('students');
}
}
(3)运行迁移
用Artisan 命令 migrate 来执行所有未执行的迁移,:
php artisan migrate
数据库生成students表,ok!
8、 数据填充
Laravel 包含一个填充类可以为你的数据库填充测试数据,所有的填充类都放在 database/seeds 目录下。你可以随意为填充类命名,但是更建议您遵守类似 UsersTableSeeder 的命名规范。seeder 类只包含一个默认方法:run 。这个方法会在执行 db:seed 这个 Artisan 命令 时被调用。在 run 方法里你可以根据需要在数据库中插入数据
(1)创建填充文件
root@ubuntu:/var/www/html/laravel# php artisan make:seeder StudentsTableSeeder
(2)打开database/seeds/新建的seeder文件,在run方法中添加一条insert语句
<?php
use Illuminate\Database\Seeder;
class StudentsTableSeeder extends Seeder{
public function run() {
//可以用 查询构造器 或 Eloquent 模型工厂 来手动插入数据
DB::table('students')->insert([
['name'=>'im','age'=>18],
['name'=>'Li','age'=>20]
]);
}
}
(3)默认情况下, db:seed 命令将运行 DatabaseSeeder 类,这个类可以用来调用其它 Seed 类。不过,你也可以使用 --class 选项来指定一个特定的 seeder 类
①执行单个填充文件
root@ubuntu:/var/www/html/laravel# php artisan db:seed --class=StudentsTableSeeder
②批量执行填充文件
root@ubuntu:/var/www/html/laravel# php artisan db:seed
(5)调用其他seeder文件
在 DatabaseSeeder 类中,你可以使用 call 方法来运行其它的 seed 类。使用 call 方法可以将数据填充拆分成多个文件,这样就不会使单个 seeder 变得非常大。只需简单传递要运行的 seeder 类名称即可:
public function run()
{
$this->call([
UsersTableSeeder::class,
PostsTableSeeder::class,
CommentsTableSeeder::class,
]);
}
(6)可以用 migrate:refresh 这个命令来填充数据库,该命令会回滚并重新运行所有迁移。这个命令可以用来重建数据库
php artisan migrate:refresh --seed
(7)生产环境中强制使用
一些填充操作可能会导致原有数据丢失,为了保护生产数据库的数据,在运行填充命令前会进行确认,可以添加 --force命令来强制运行填充命令
php artisan db:seed --force
9、请求
public function index(Request $request){
$request->isMethod('POST');//判断请求类型
$request->method();//获取请求类型
$request->ajax();//是否是ajax请求
$request->has('name');//检测请求参数
$request->input('name');//获取参数值
$request->all();//获取所有请求参数
$request->hasFile('file1');//检测是否有文件上传
$request->cookie();//获取cookie
$request->url();//获取完整url
$request->path();//返回请求路径信息,只返回student/index
$request->is('student/*');//验证请求的路径是否与给定的模式匹配
}
10、session
session的配置文件在config/session文件中,默认session驱动为file。
lavarel中启动session的方法:
在Http/Kernel.php中$middlewareGroups中间件组中有StartSession那一行,所以在路由中把web中间件加上就可以。
web.php
Route::group(['middleware'=>'web'],function(){
Route::get('student/index','StudentController@index');
Route::get('student/index2','StudentController@index2');
});
Lavarel中session有3中方式:
public function index(){
//(1)request类的session方法
$request->session()->put('key1','value1');
echo $request->session()->get('key1');
//(2)session()辅助函数
session()->put('key2','value2');
echo session()->get('key2');
//(3)session facade
Session::put('key3','value3');
echo Session::get('key3');
}
详解session facade
public function index(){
//存储数据到session
Session::put('key3','value3');
Session::put(['key3'=>'value3']);//以数组形式
//获取session的值,get()第二个参数为默认值
echo Session::get('key4','default');
//把数据放到数组中
Session::push('student','im');
Session::push('student','La');
$array=Session::get('student');
//数据取出后立即删除
$array=Session::pull('student');
//暂存数据,只有第一次访问的时候存在
Session::flash('key5','value5');
echo Session::get('key5');
//取出session所有数据
$array=Session::all();
//判断session中某个key是否存在
$bool=Session::has('key3');
//删除某个key
Session::forget('key3');
//清空所有session信息
Session::flush();
}
11、响应
响应常见类型:字符串、视图、json、重定向
(1)响应json
public function index(){
$data=array(
'error'=>0,
'msg'=>'success'
);
return response()->json($data);//结果:{"error":0,"msg":"success"}
}
(2)重定向
public function session1(){
return Session::get('message');
}
public function index(){
//重定向1:重定向并使用闪存的 Session 数据
//可以通过session取出success的值
return redirect('student/session1')->with('success','我只显示一次,第二次就没有了');
//重定向2
return redirect()->action('StudentController@session1')->with('message','我只显示一次,第二次就没有了');
//重定向3
return redirect()->route('session1')->with('利用路由别名重定向');
}
//重定向4 :返回上一次url
return redirect()->back();
12、中间件
中间件提供了一种方便的机制过滤进入应用程序的 HTTP 请求。
//Controller
class TestController extends Controller
{
public function activity0(){
return '活动未开始';
}
public function activity1(){
return '活动1开始了';
}
public function activity2(){
return '活动2开始了';
}
}
(1)新建中间件
app/Http/Middleware文件夹下新建Activity.php,也可以使用php artisan make:middleware Activity命令创建。
<?php
namespace App\Http\Middleware;
use Closure;
class Activity{
public function handle($request,Closure $next){
//如果时间小于2020-01-09就跳转到activity0方法
if(time()<strtotime('2020-01-09')){
return redirect('activity0');
}
return $next($request);
}
}
?>
(2)注册中间件
打开app/Http/Kernel.php:
如果你希望中间件在应用处理每个 HTTP 请求期间运行。
①如果需要所有路由都必须经过此中间件,则在middlerware属性中列出这个中间件即可。
②如果只为指定的路由分配中间件,则在routeMiddleware 属性中注册自定义的路由,然后需要在 routes/web.php 中将中间件绑定到指定的路由。
protected $routeMiddleware = [
.....
//新加
'activity' => \App\Http\Middleware\Activity::class,
];
(3)使用中间件:在routes/web.php
Route::any('activity0','TestController@activity0');
Route::group(['middleware'=>'activity'],function(){
Route::any('activity1','TestController@activity1');
Route::any('activity2','TestController@activity2');
});
//为单个路由分配多个中间件
//Route::any('activity1', 'TestController@activity1')->->middleware('first', 'second');
(4)前置和后置操作
中间件是在请求之前或之后执行,取决于中间件本身。
前置:
public function handle($request, Closure $next){
// 执行一些任务
return $next($request);
}
后置:
public function handle($request, Closure $next){
$response = $next($request);
// 执行一些任务
return $response;
}
13、auth认证
(1)路由
Laravel 的 laravel/ui 包提供了一种快速方法,可以使用一些简单的命令来支持你进行身份验证所需的所有路由和视图。
user@bogon:/var/www/html/laravel$ composer require laravel/ui
①这个命令安装布局视图,注册和登录视图以及所有身份验证端点的路由。 还将生成一个 HomeController 来处理应用程序仪表板的登录后请求。
②如果应用程序不需要注册,可以通过删除新创建的 RegisterController 并修改路由声明来禁用它:Auth::routes([‘register’ => false]);
(2)视图
该命令创建的视图放在resources/views/auth,还将创建一个 resources/views/layouts 目录,其中包含应用程序的基本布局;
(3)自定义路径
用户认证成功后,会重定向到/home这个url下,你可以在 LoginController,RegisterController,ResetPasswordController还有 VerificationController 控制器中定义 redirectTo 属性来自定义验证后的重定向位置:
protected $redirectTo = '/';
//或者
protected function redirectTo()
{
return '/';
}
接下,你应该修改 RedirectIfAuthenticated 中间件中的 handle 方法,以便在重定向用户时重定向到新的 URI。
(4)自定义用户名
laravel默认使用email进行验证,如果想使用其他字段,可以再LoginController.php中定义一个username方法
public function username(){
return 'username';
}
(5)保护路由
Route::get('profile', function () {
// ...
})->middleware('auth');
//
Route::group(['middleware'=>'auth'],function(){
Route::any( 'blog/index',['as'=>'blog/index','uses'=>'BlogController@index']);
Route::match(['get','post'],'blog/update/{id}',['as'=>'blog/update','uses'=>'BlogController@update']);
Route::get('blog/del/{id}','BlogController@del');
});
//
//控制器中
public function __construct(){
$this->middleware('auth');
}