laravel学习总结

目录

什么是laravel框架

Laravel的基本使用,laravel使用

Laravel的基本数据库操作部分,laravel数据库

Laravel 路由

分组 1. Route::resource 和 Route::apiResource

分组 2. 嵌套子路由组

分组 3. 将重复的中间件分组

分组 4. 同名控制器,不同命名空间

分组 5. 分离路由文件

分组 6. Laravel 9 中的新功能: Route::controller ()

控制器

基本控制器

控制器 & 命名空间

命名控制器路由

控制器中间件

RESTful 资源控制器

资源控制器所处理的行为

部分资源路由

命名资源路由

命名资源路由参数

资源控制器中意外的行为

依赖注入 & 控制器

构造器注入

方法注入

缓存路由


什么是laravel框架

Laravel是泰勒·奥特威尔(Taylor Otwell)使用PHP语言开发的一款开源的Web应用框架。

于2011年6月首次发布,发布以来备受PHP开发人员的喜爱,用户的增长速度十分迅猛

Laravel是一套简洁优雅的框架,具有简洁且富于表达性的语法

Laravel秉承“Don't Repeat Yourself”(不要重复你自己)的理念,提倡代码的重用

Laravel为开发大型应用提供了强大的功能,包括自动验证路由Session缓存数据库迁移等Laravel框架的特点:

1.对外只提供一个入口,让框架统一管理项目的所有的请求。

2.采用MVC设计模式,帮助团队更好地协同开发,为项目后期的维护提供方便。

3.支持Composer依赖管理工具,可以为项目自动安装依赖。

4.采用ORM方式操作数据库,支持AR模式。

5.注重代码的模块化可扩展性开发者可以通过Laravel组件库Packalyst找到想要添加的组件。

6.自带各种方便的服务,提供开箱即用的用户身份验证功能和缓存系统,可以快速开发出相应的功能。

7.具有路由功能Laravel框架通过路由分发每一个请求,并可以对请求进行分组。

提供Artisan命令行工具帮助开发人员将手动的工作自动化

Laravel的基本使用,laravel使用

[Laravel] Laravel的基本HTTP路由

使用Laravel的基本路由,实现get请求响应,找到文件app/Http/routes.php

调用Route的静态方法get(),实现get响应,参数:string类型的路径,匿名函数function(){}

匿名函数内部,返回string数据

实现post,put,delete的请求,同上

实现get传递参数的路由,调用Route的静态方法get(),参数:路径,匿名函数

路径,大括号包裹参数名,不含$,例如:’/user/{id}’

匿名函数,接收参数,例如:function($id){}

[Laravel] Laraval的基本控制器

在app/Http/Controllers目录下,新建一个Index/IndexController.php

定义命名空间,namespace App\Http\Controllers\Index

引入Controller基本控制器,use App\Http\Controllers\Controller

定义IndexController继承Controller

实现方法index,返回数据

定义路由指定控制器的行为,例如:Route::get("/index","Index\IndexController@index");,

注意命名空间部分,新建的控制器是在根命名空间下面,指定的时候添加自己新加的命名空间

[Laravel] Laravel的基本视图

在目录resources/views/下面,创建index/index.php

在控制器中使用函数view()来调用模板,参数:文件路径(.分隔目录),数据

路由:routes.php

php

/*
|--------------------------------------------------------------------------
| Routes File
|--------------------------------------------------------------------------
|
| Here is where you will register all of the routes in an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
/*测试get post*/ 
Route::get('/', function () {
    $url=url("index");
    return "Hello World".$url;
    //return view('welcome');
});
Route::post("/post",function(){
    return "测试post";
});

/*传递参数*/
Route::get("/user/{id}",function($id){
    return "用户".$id;
});
/*使用控制器*/
Route::get("/index","Index\IndexController@index");
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| This route group applies the "web" middleware group to every route
| it contains. The "web" middleware group is defined in your HTTP
| kernel and includes session state, CSRF protection, and more.
|
*/

Route::group(['middleware' => ['web']], function () {
    //
});

控制器:IndexController.php

php
namespace App\Http\Controllers\Index;

use App\Http\Controllers\Controller;
class IndexController extends Controller{
    public function index(){
        $data=array();
        $data['title']="Index控制器";
        return view("index.index",$data);
    }
}

模板:index.php

    
        
php echo $title;?>div> div> div> body>

Laravel的基本数据库操作部分,laravel数据库

[laravel] laravel的数据库配置

找到程序目录结构下.env文件

配置基本的数据库连接信息

DB_HOST=127.0.0.1

DB_PORT=3306

DB_DATABASE=blog

DB_USERNAME=root

DB_PASSWORD=root

修改完.env文件需要重启服务

[laravel] laravel的数据库入门

控制器中导入DB数据库操作类,use DB

使用DB类的静态方法select来查询数据库,DB::select(),参数:sql语句,参数值数组

例如:$user=DB::select("select * from article where id=?",array("1"));

获取到一个数组,数组中的每一个结果是一个StdClass对象

php
namespace App\Http\Controllers\Index;
use App\Http\Controllers\Controller;
use DB;
class IndexController extends Controller{
    public function index(){
        $data=array();
        $data['title']="Index控制器";

        // 第一种
        $user=DB::select("select * from article where id=?",array("1"));
        foreach ($user as $v) {
            echo $v->title;
        }
        // 第二种
        $users=DB::table("article")->get();
        foreach ($user as $v) {
            echo $v->title;
        }
        return view("index.index",$data);
    }
}

使用查询构造器

使用DB::table(),得到查询构造器对象,参数:表名

调用Builder对象的get()方法,得到数组数据

例如:$users=DB::table("article")->get();

查询构造器是链式调用的,还有其他方法,可以去查看文档

[laravel] 数据库的迁移

使用Artisan命令创建迁移,make:migration 名称 –create 表名

例如:php artisan make:migration create_users_table --create=users

此命令会在database/migrations目录下面创建一个迁移文件

打开生成的迁移文件,在up方法里面进行字段的创建,这里会用到数据库的结构构造器Schema

运行迁移命令,使用命令 php artisan migrate,会在数据库中自动创建表

[laravel] Eloquent模型

使用Eloquent模型为表建立映射模型ORM,使用Artisan命令 make:model 模型名称

例如:php artisan make:model User

在app目录下生成一个User.php的模型文件

Laravel 路由

是开发人员从一开始就学习的特性。但是随着他们项目的增长,管理不断增长的路由文件变得越来越困难,经常需要滚动查找正确的 Route::get() 语句。幸运的是,有一些技术可以使路由文件更短、更易读,让我们来看看以不同的方式对路由及其设置进行分组。

我们不会只谈论一般简单的 Route::group(),那是初学者级别。 让我们再深入一点。


分组 1. Route::resource 和 Route::apiResource

让我们从房间里的大象开始:这可能是最常用的分组。如果您围绕一个模型有一组典型的 CRUD 操作,则应该将它们分组到 资源控制器

此类控制器包含 多达 7 种方法(但可能更少):

  • index()
  • create()
  • store()
  • show()
  • edit()
  • update()
  • destroy()

因此,如果您的路由集对应于这些方法,请不要使用:

1

2

3

4

5

6

7

Route::get('books', [BookController::class, 'index'])->name('books.index');

Route::get('books/create', [BookController::class, 'create'])->name('books.create');

Route::post('books', [BookController::class, 'store'])->name('books.store');

Route::get('books/{book}', [BookController::class, 'show'])->name('books.show');

Route::get('books/{book}/edit', [BookController::class, 'edit'])->name('books.edit');

Route::put('books/{book}', [BookController::class, 'update'])->name('books.update');

Route::delete('books/{book}', [BookController::class, 'destroy'])->name('books.destroy');

… 您可能只有一行:

1

Route::resource('books', BookController::class);

如果您使用 API 项目,则不需要用于创建 / 编辑的可视化表单,因此您可以使用 apiResource() 的涵盖 7 种方法中的 5 种不同语法:

1

Route::apiResource('books', BookController::class);

此外,我建议您考虑资源控制器,即使您有 2-4 个方法,而不是完整的 7 个。只是因为它保持标准命名约定 - 对于 URL、方法和路由名称。 例如,在这种情况下,您不需要手动提供名称:

1

2

3

4

5

Route::get('books/create', [BookController::class, 'create'])->name('books.create');

Route::post('books', [BookController::class, 'store'])->name('books.store');

// 相反,这里的名称“books.create”和“books.store”是自动分配的

Route::resource('books', BookController::class)->only(['create', 'store']);


分组 2. 嵌套子路由组

当然,一般的 路由分组 大家都知道。 但对于更复杂的项目,一级分组可能还不够。

实际示例:您希望授权路由与 auth 中间件进行分组,但在内部您需要分隔更多子组,例如管理员和简单用户。

1

2

3

4

5

6

7

8

9

10

Route::middleware('auth')->group(function() {

    Route::middleware('is_admin')->prefix('admin')->group(function() {

     Route::get(...) // administrator routes

    });

    Route::middleware('is_user')->prefix('user')->group(function() {

     Route::get(...) // user routes

    });

});


分组 3. 将重复的中间件分组

如果你有很多中间件,有一些在路由组中重复出现怎么办?

1

2

3

4

5

6

7

Route::prefix('students')->middleware(['auth', 'check.role', 'check.user.status', 'check.invoice.status', 'locale'])->group(function () {

    // ... 学生路由

});

Route::prefix('managers')->middleware(['auth', 'check.role', 'check.user.status', 'locale'])->group(function () {

    // ... 管理员路由

});

如您所见,有 5 个中间件,其中 4 个是重复的。因此,在 app/Http/Kernel.php 文件里,我们可以将这 4 个移动到单独的中间件组中:

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

protected $middlewareGroups = [

    // 此组是 Laravel 默认中间件组

    'web' => [

        \App\Http\Middleware\EncryptCookies::class,

        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,

        \Illuminate\Session\Middleware\StartSession::class,

        \Illuminate\View\Middleware\ShareErrorsFromSession::class,

        \App\Http\Middleware\VerifyCsrfToken::class,

        \Illuminate\Routing\Middleware\SubstituteBindings::class,

    ],

    // 此组是 Laravel 默认中间件组

    'api' => [

        // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,

        'throttle:api',

        \Illuminate\Routing\Middleware\SubstituteBindings::class,

    ],

    // 这是我们新的中间件组

    'check_user' => [

        'auth',

        'check.role',

        'check.user.status',

        'locale'

    ],

];

所以将我们的中间件组命明为 check_user,现在我们可以缩写路由:

1

2

3

4

5

6

7

Route::prefix('students')->middleware(['check_user', 'check.invoice.status'])->group(function () {

    // ... student routes

});

Route::prefix('managers')->middleware(['check_user'])->group(function () {

    // ... manager routes

});


分组 4. 同名控制器,不同命名空间

很常见的情况是,例如,为不同的用户角色设置了 HomeController,例如 Admin/HomeController 和 User/HomeController。 如果在路由中使用完整路径,它看起来像这样:

1

2

3

4

5

6

7

Route::prefix('admin')->middleware('is_admin')->group(function () {

    Route::get('home', [\App\Http\Controllers\Admin\HomeController::class, 'index']);

});

Route::prefix('user')->middleware('is_user')->group(function () {

    Route::get('home', [\App\Http\Controllers\User\HomeController::class, 'index']);

});

每个控制器都是用了完整的路径这看上去很冗余,对吧? 这就是为什么许多开发人员更喜欢在路由列表中只包含 HomeController::class 并在顶部添加类似这样的内容:

1

use App\Http\Controllers\Admin\HomeController;

但是这里的问题是我们有相同的控制器类名! 所以,这行不通:

1

2

use App\Http\Controllers\Admin\HomeController;

use App\Http\Controllers\User\HomeController;

哪一个是「管理后台」的控制器?好吧,一种方法是更改名称并为其中之一分配别名:

1

2

3

4

5

6

7

8

9

10

use App\Http\Controllers\Admin\HomeController as AdminHomeController;

use App\Http\Controllers\User\HomeController;

Route::prefix('admin')->middleware('is_admin')->group(function () {

    Route::get('home', [AdminHomeController::class, 'index']);

});

Route::prefix('user')->middleware('is_user')->group(function () {

    Route::get('home', [HomeController::class, 'index']);

});

但是,就个人而言,更改顶部类的名称让我很困惑,我喜欢另一种方法:为控制器的子文件夹添加一个命名空间():

1

2

3

4

5

6

7

8

9

Route::prefix('admin')->namespace('App\Http\Controllers\Admin')->middleware('is_admin')->group(function () {

    Route::get('home', [HomeController::class, 'index']);

    // ... Admin 命名空间中的其他控制器

});

Route::prefix('user')->namespace('App\Http\Controllers\User')->middleware('is_user')->group(function () {

    Route::get('home', [HomeController::class, 'index']);

    // ... 来自用户命名空间的其他控制器

});


分组 5. 分离路由文件

如果你觉得 routes/web.php 或 routes/api.php 太大了,可以把一些路由放到一个单独的文件中,你可以为它任意命名,例如 routes/admin.php

要加载该文件,有两种方法:我称之为 「Laravel 方式」 和 「PHP 方式」 。

如果你想遵循 Laravel 构建其默认路由文件的结构,查看 app/Providers/RouteServiceProvider.php :

1

2

3

4

5

6

7

8

9

10

11

12

13

public function boot()

{

    $this->configureRateLimiting();

    $this->routes(function () {

        Route::middleware('api')

            ->prefix('api')

            ->group(base_path('routes/api.php'));

        Route::middleware('web')

            ->group(base_path('routes/web.php'));

    });

}

routes/api.php 和 routes/web.php 都在这里,但设置略有不同。因此,你只需要在此处添加 admin 文件:

1

2

3

4

5

6

7

8

9

10

11

$this->routes(function () {

    Route::middleware('api')

        ->prefix('api')

        ->group(base_path('routes/api.php'));

    Route::middleware('web')

        ->group(base_path('routes/web.php'));

    Route::middleware('is_admin')

        ->group(base_path('routes/admin.php'));

});

如果你不想深入研究 服务提供者,还有一种更简单的方法 - 只需 include/require 您的路由文件到另一个文件中,就像你在 Laravel 框架之外的任何 PHP 文件。

事实上,这是由 Taylor Otwell 完成的,只需将 routes/auth.php 文件直接放入 Laravel Breeze 路由:

routes/web.php:

1

2

3

4

5

6

7

8

9

Route::get('/', function () {

    return view('welcome');

});

Route::get('/dashboard', function () {

    return view('dashboard');

})->middleware(['auth'])->name('dashboard');

require __DIR__.'/auth.php';


分组 6. Laravel 9 中的新功能: Route::controller ()

如果你的 Controller 中有一些方法,但它们不遵循标准的 Resource 结构,您仍然可以对它们进行分组,而无需为每个方法重复 Controller 名称。

取而代之的是:

1

2

3

Route::get('profile', [ProfileController::class, 'getProfile']);

Route::put('profile', [ProfileController::class, 'updateProfile']);

Route::delete('profile', [ProfileController::class, 'deleteProfile']);

您可以这样做:

1

2

3

4

5

Route::controller(ProfileController::class)->group(function() {

    Route::get('profile', 'getProfile');

    Route::put('profile', 'updateProfile');

    Route::delete('profile', 'deleteProfile');

});

此功能在 Laravel 9 和 Laravel 8 的最新小版本中可用。

控制器

基本控制器

一个基本的控制器应该继承自App\Http\Controllers\Controller控制器类:

 User::findOrFail($id)]);  }}`

我们可以通过下面的方式把控制器的行为分配到路由:

Route::get('user/{id}', 'UserController@showProfile');

一旦将控制器的行为分配到路由之后,每次客户端请求该路由,都会触发控制器的行为。这里即客户端每次请求user/{id}路由,showProfile方法都会被执行,路由中的参数也会被直接传递到该方法中.

控制器 & 命名空间

你应该知道我们在定义控制器路由时是不需要指定控制器的命名空间的,而只需要指定到类名就可以了,这是因为在RouteServiceProvider文件中自动加载的routes.php文件已经被指定了路由组的根命名空间App\Http\Controllers;

如果你想在App\Http\Controllers目录下使用php命名空间来嵌套或组织控制器,那么你只需要简单的指定相对于App\Http\Controllers部分的类名就可以了。所以如果你的控制器的全部类名为App\Http\Controllers\Photos\AdminController,那么你就可以这样来定义控制器路由:

Route::get('foo', 'Photos\AdminController@method');

命名控制器路由

就像定义命名路由一样,我们也可以给一个控制器路由命名:

Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']);

一旦你为一个路由进行了命名, 那么你就可以通过route帮助方法去快速的生成被命名路由的资源表述地址:

$url = route('name');

控制器中间件

中间件可以这样被分配到控制器路由中:

Route::get('profile', [  'middleware' => 'auth',  'uses' => 'UserController@showProfile']);

当然你也可以在控制器类中直接使用middleware方法来进行中间件的分配,你也可以只允许类中的某些行为受到指定中间件的约束:

class UserController extends Controller {  public function __construct() {    $this->middleware('auth');    $this->middleware('log', ['only' => [      'fooAction',      'barAction'    ]]);    $this->middleware('subscribed', ['except' => [      'fooAction',      'barAction'    ]]);  }}

RESTful 资源控制器

资源控制器可以使你快速的构建RESTful型的控制器。你可以使用artisan命令来快速的创建:

php artisan make:controller PhotoController --resource

该命令会生成app\Http\Controllers\PhotoController.php文件,资源控制器中将包含每个可用的资源操作相应的方法.

你可以通过下面的方式来进行资源路由的注册:

Route::resource('photo', 'PhotoController');

这一个简单的声明会创造多条路由用来处理RESTful式的请求.相应的通过命令生成的资源型控制器也为这些请求设置了对应的处理方法.

资源控制器所处理的行为

请求方式 路由地址 控制器行为 路由命名
GET /photo index photo.index
GET /photo/create create photo.create
POST /photo store photo.store
GET /photo/{photo} show photo.show
GET /photo/{photo}/edit edit photo.edit
PUT/PATCH /photo/{photo} update photo.update
DELETE /photo/{photo} destroy photo.destroy

部分资源路由

有时候你可能并不想控制器处理全部的请求方式,那么你可以这么做:

Route::resource('photo', 'PhotoController', ['only' => [  'index', 'show']]);Route::resource('photo', 'PhotoController', ['except' => [  'create', 'store', 'update', 'destroy']]);

命名资源路由

默认的,所有的资源控制器行为都被进行了相应的路由命名,你可以通过names参数来进行重命名:

Route::resource('photo', 'PhotoController', ['names' => [  'create' => 'photo.build']]);

命名资源路由参数

默认的,资源路由的路由参数都被命名为相应的资源名称,你可以用过parameters参数来进行重命名:

Route::resource('user', 'AdminUserController', ['parameters' => [  'user' => 'admin_user']]);// /user/{admin_user}

有时候你可能希望资源路由的路由参数并不需要像默认的资源名称一样采取复数的形式,那么你可以通过传递parameters的选项设置为singular:

Route::resource('users.photos', 'PhotoController', [  'parameters' => 'singular']);// /users/{user}/photos/{photo}

另外,你也可以全局设置你的资源路由参数为单数形式或者全局进行资源路由参数的命名映射:

Route::singularResourceParameters();Route::resourceParameters([  'user' => 'person',  'photo' => 'image'])

当你对资源路由参数进行定制时,你应该清楚的知道命名的顺序优先级:

  1. 参数被直接的传递给Route::resource
  2. 通过 Router::resourceParameters 进行全局参数映射
  3. 通过parameters数组选项传递给Route::resource 或者 通过 Route::singularResoureParameters 进行单数形式参数设置
  4. 默认行为

资源控制器中意外的行为

如果你必须在资源控制器中添加额外的行为去注册相应的路由,那么你一定要在使用Route::resource之前进行注册,否则该行为很可能会被资源控制器意外的覆盖掉.

Route::get('photos/popular', 'PhotoController@method');Route::resource('photos', 'PhotoController');

依赖注入 & 控制器

构造器注入

laravel的服务容器支持所有的laravel控制器的解析。由于这个原因,所以你可以在控制器的构造函数中添加你所需要依赖的相应类型提示,这些依赖会被自动的解析并注入进控制器实例.

users = $users;  }}

当然,你也被允许添加一些laravel contract的类型提示,只要服务容器能够正确的解析,你都可以被允许添加。

方法注入

除了在构造函数中进行依赖注入,你也可以在控制器的行为方法中进行依赖注入,比如,将Illuminate\Http\Reqeust实例注入到控制器的store方法中:

input('name');  }}

如果你的控制器方法也接收从路由传递过来的参数,那么他们会在其它依赖解析完毕之后被传递,比如你的路由是这么定义的:

Route::put('user/{id}', 'UserController@update');

那么你可以这么修正你的控制器行为,来进行参数的接收:

 
  

缓存路由

注意:缓存路由不支持闭包函数定义的路由,如果你想使你的路由被缓存,那么你应该使用控制器来管理你的路由.

如果你所有的路由都是基于控制器的路由,那么你应该使用laravel推荐的缓存路由,你可以简单的通过artisan命令来缓存所有路由注册到同一个文件里,它会替代routes.php文件被解析,使用这种缓存注册路由的方式在某些情况下注册路由的时间将被大大的减少,从而提高了应用的响应速度。但是每次添加新的路由或者删除路由时,为了使路由生效,你需要重新生成一次缓存路由:

php artisan route:cache

你可以通过下面的方式去删除路由缓存:

php artisan route:clear

你可能感兴趣的:(laravel,学习,php)