Laravel作为在国内国外都颇为流行的PHP框架,风格优雅,其拥有自己的一些特点。

 

. 请求周期

  Laravel 采用了单一入口模式,应用的所有请求入口都是 public/index.php 文件。

  1. 注册类文件自动加载器:Laravel通过composer进行依赖管理,并在bootstrap/autoload.php中注册了Composer Auto Loader (PSR-4),应用中类的命名空间将被映射到类文件实际路径,不再需要开发者手动导入各种类文件,而由自动加载器自行导入。因此,Laravel允许你在应用中定义的类可以自由放置在Composer Auto Loader能自动加载的任何目录下,但大多数时候还是建议放置在app目录下或app的某个子目录下

  2. 创建服务容器:从 bootstrap/app.php 文件中取得 Laravel 应用实例 $app (服务容器)

  3. 创建 HTTP / Console 内核:传入的请求会被发送给 HTTP 内核或者 console 内核进行处理,HTTP 内核继承自 Illuminate\Foundation\Http\Kernel 类。它定义了一个 bootstrappers 数组,数组中的类在请求真正执行前进行前置执行,这些引导程序配置了错误处理,日志记录,检测应用程序环境,以及其他在请求被处理前需要完成的工作;HTTP 内核同时定义了一个 HTTP 中间件列表,所有的请求必须在处理前通过这些中间件处理 HTTP session 的读写,判断应用是否在维护模式, 验证 CSRF token 等等

  4. 载入服务提供者至容器:在内核引导启动的过程中最重要的动作之一就是载入服务提供者到你的应用,服务提供者负责引导启动框架的全部各种组件,例如数据库、队列、验证器以及路由组件。因为这些组件引导和配置了框架的各种功能,所以服务提供者是整个 Laravel 启动过程中最为重要的部分,所有的服务提供者都配置在 config/app.php 文件中的 providers 数组中。首先,所有提供者的 register 方法会被调用;一旦所有提供者注册完成,接下来,boot 方法将会被调用

  5. 分发请求:一旦应用完成引导和所有服务提供者都注册完成,Request 将会移交给路由进行分发。路由将分发请求给一个路由或控制器,同时运行路由指定的中间件

     

二. 服务容器和服务提供者

  服务容器是 Laravel 管理类依赖和运行依赖注入的有力工具,在类中可通过 $this->app 来访问容器,在类之外通过 $app 来访问容器;服务提供者是 Laravel 应用程序引导启动的中心,关系到服务提供者自身、事件监听器、路由以及中间件的启动运行。应用程序中注册的路由通过RouteServiceProvider实例来加载;事件监听器在EventServiceProvider类中进行注册;中间件又称路由中间件,在app/Http/Kernel.php类文件中注册,调用时与路由进行绑定。在新创建的应用中,AppServiceProvider 文件中方法实现都是空的,这个提供者是你添加应用专属的引导和服务的最佳位置,当然,对于大型应用你可能希望创建几个服务提供者,每个都具有粒度更精细的引导。服务提供者在 config/app.php 配置文件中的providers数组中进行注册

万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

<?php

namespace App\Providers;use Riak\Connection;use Illuminate\Support\ServiceProvider;class RiakServiceProvider extends ServiceProvider
{    /**
     * 在容器中注册绑定
     *
     * @return void     */
    public function register()
    {        $this->app->singleton(Connection::class, function ($app) {            return new Connection(config('riak'));
        });
    }
}

万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

  

三. 依赖注入

  Laravel 实现依赖注入方式有两种:自动注入和主动注册。自动注入通过参数类型提示由服务容器自动注入实现;主动注册则需开发人员通过绑定机制来实现,即绑定服务提供者或类(参考: http://d.laravel-china.org/docs/5.4/container )。

  1. 绑定服务提供者或类:这种方式对依赖注入的实现可以非常灵活多样

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

    use Illuminate\Support\Facades\Storage;use App\Http\Controllers\PhotoController;use App\Http\Controllers\VideoController;use Illuminate\Contracts\Filesystem\Filesystem;$this->app->when(PhotoController::class)          ->needs(Filesystem::class)          ->give(function () {              return Storage::disk('local');
              });$this->app->when(VideoController::class)          ->needs(Filesystem::class)          ->give(function () {              return Storage::disk('s3');
              });

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

  2. 参数类型声明:通过对类的构造器参数类型、类的方法参数类型、闭包的参数类型给出提示来实现

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

    <?php
    
    namespace App\Http\Controllers;use App\Users\Repository as UserRepository;class UserController extends Controller
    {    /**
         * user repository 实例。     */
        protected $users;    /**
         * 控制器构造方法。
         *
         * @param  UserRepository  $users
         * @return void     */
        public function __construct(UserRepository $users)
        {        $this->users = $users;
        }    /**
         * 储存一个新用户。
         *
         * @param  Request  $request
         * @return Response     */
        public function store(Request $request)
        {        $name = $request->input('name');        //    }
    }

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

  3. 路由参数依赖:下边的示例使用 Illuminate\Http\Request 类型提示的同时还获取到路由参数id

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

    你的路由可能是这样定义的:Route::put('user/{id}', 'UserController@update');而控制器对路由参数id的依赖却可能是这样实现的:<?php
    
    namespace App\Http\Controllers;use Illuminate\Http\Request;class UserController extends Controller
    {    /**
         * 更新指定的用户。
         *
         * @param  Request  $request
         * @param  string  $id
         * @return Response     */
        public function update(Request $request, $id)
        {        //    }
    }

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

     

四. Artisan Console 

  Laravel利用PHP的CLI构建了强大的Console工具artisan,artisan几乎能够创建任何你想要的模板类以及管理配置你的应用,在开发和运维管理中扮演着极其重要的角色,artisan是Laravel开发不可或缺的工具。在Laravel根目录下运行:PHP artisan list可查看所有命令列表。用好artisan能极大地简化开发工作,并减少错误发生的可能;另外,还可以编写自己的命令。下面列举部分比较常用的命令:

  • 启用维护模式:php artisan down --message='Upgrading Database' --retry=60

  • 关闭维护模式:php artisan up

  • 生成路由缓存:php artisan route:cache

  • 清除路由缓存:php artisan route:clear

  • 数据库迁移 Migrations:php artisan make:migration create_users_table --create=users

  • 创建资源控制器:php artisan make:controller PhotoController --resource --model=Photo

  • 创建模型及迁移:php artisan make:model User -m

 

五. 表单验证机制

  表单验证在web开发中是不可或缺的,其重要性也不言而喻,也算是每个web框架的标配部件了。Laravel表单验证拥有标准且庞大的规则集,通过规则调用来完成数据验证,多个规则组合调用须以“|”符号连接,一旦验证失败将自动回退并可自动绑定视图。

  下例中,附加bail规则至title属性,在第一次验证required失败后将立即停止验证;“.”语法符号在Laravel中通常表示嵌套包含关系,这个在其他语言或框架语法中也比较常见

$this->validate($request, [    'title' => 'bail|required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',]);

Laravel验证规则参考 http://d.laravel-china.org/docs/5.4/validation#可用的验证规则 ;另外,在Laravel开发中还可采用如下扩展规则:

  1. 自定义FormRequest (须继承自 Illuminate\Foundation\Http\FormRequest )

  2. Validator::make()手动创建validator实例

  3. 创建validator实例验证后钩子

  4. 按条件增加规则

  5. 数组验证

  6. 自定义验证规则

 

六. 事件机制

  Laravel事件机制是一种很好的应用解耦方式,因为一个事件可以拥有多个互不依赖的监听器。事件类 (Event) 类通常保存在 app/Events 目录下,而它们的监听类 (Listener) 类被保存在 app/Listeners 目录下,使用 Artisan 命令来生成事件和监听器时他们会被自动创建。

  1. 注册事件和监听器:EventServiceProvider的 listen 属性数组用于事件(键)到对应的监听器(值)的注册,然后运行 php artisan event:generate将自动生成EventServiceProvider中所注册的事件(类)模板和监听器模板,然后在此基础之上进行修改来实现完整事件和监听器定义;另外,你也可以在 EventServiceProvider 类的 boot 方法中通过注册闭包事件来实现

  2. 定义事件(类):事件(类)就是一个包含与事件相关信息数据的容器,不包含其它逻辑

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

     1 <?php 2  3 namespace App\Events; 4  5 use App\Order; 6 use Illuminate\Queue\SerializesModels; 7  8 class OrderShipped 9 {10     use SerializesModels;11 12     public $order;13 14     /**15      * 创建一个事件实例。16      *17      * @param  Order  $order18      * @return void19      */20     public function __construct(Order $order)21     {22         $this->order = $order;23     }24 }

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

  3. 定义监听器:事件监听器在 handle 方法中接受了事件实例作为参数

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

     1 <?php 2  3 namespace App\Listeners; 4  5 use App\Events\OrderShipped; 6  7 class SendShipmentNotification 8 { 9     /**10      * 创建事件监听器。11      *12      * @return void13      */14     public function __construct()15     {16         //17     }18 19     /**20      * 处理事件21      *22      * @param  OrderShipped  $event23      * @return void24      */25     public function handle(OrderShipped $event)26     {27         // 使用 $event->order 来访问 order ...28     }29 }

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

  4. 停止事件传播:在监听器的 handle 方法中返回 false 来停止事件传播到其他的监听器

  5. 触发事件:调用 event 辅助函数可触发事件,事件将被分发到它所有已经注册的监听器上

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

     1 <?php 2  3 namespace App\Http\Controllers; 4  5 use App\Order; 6 use App\Events\OrderShipped; 7 use App\Http\Controllers\Controller; 8  9 class OrderController extends Controller10 {11     /**12      * 将传递过来的订单发货。13      *14      * @param  int  $orderId15      * @return Response16      */17     public function ship($orderId)18     {19         $order = Order::findOrFail($orderId);20 21         // 订单的发货逻辑...22 23         event(new OrderShipped($order));24     }25 }

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

  6. 队列化事件监听器:如果监听器中需要实现一些耗时的任务,比如发送邮件或者进行 HTTP 请求,那把它放到队列中处理是非常有用的。在使用队列化监听器,须在服务器或者本地环境中配置队列并开启一个队列监听器,还要增加 ShouldQueue 接口到你的监听器类;如果你想要自定义队列的连接和名称,你可以在监听器类中定义 $connection 和 $queue 属性;如果队列监听器任务执行次数超过在工作队列中定义的最大尝试次数,监听器的 failed 方法将会被自动调用

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

     1 <?php 2  3 namespace App\Listeners; 4  5 use App\Events\OrderShipped; 6 use Illuminate\Contracts\Queue\ShouldQueue; 7  8 class SendShipmentNotification implements ShouldQueue 9 {10     /**11      * 队列化任务使用的连接名称。12      *13      * @var string|null14      */15     public $connection = 'sqs';16 17     /**18      * 队列化任务使用的队列名称。19      *20      * @var string|null21      */22     public $queue = 'listeners';23 24     public function failed(OrderShipped $event, $exception)25     {26         //27     }       
    28 }

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

  7. 事件订阅者:事件订阅者允许在单个类中定义多个事件处理器,还应该定义一个 subscribe 方法,这个方法接受一个事件分发器的实例,通过调用事件分发器的 listen 方法来注册事件监听器,然后在 EventServiceProvider 类的 $subscribe 属性中注册订阅者

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

     1 <?php 2  3 namespace App\Listeners; 4  5 class UserEventSubscriber 6 { 7     /** 8      * 处理用户登录事件。 9      */10     public function onUserLogin($event) {}11 12     /**13      * 处理用户注销事件。14      */15     public function onUserLogout($event) {}16 17     /**18      * 为订阅者注册监听器。19      *20      * @param  Illuminate\Events\Dispatcher  $events21      */22     public function subscribe($events)23     {24         $events->listen(25             'Illuminate\Auth\Events\Login',26             'App\Listeners\UserEventSubscriber@onUserLogin'27         );28 29         $events->listen(30             'Illuminate\Auth\Events\Logout',31             'App\Listeners\UserEventSubscriber@onUserLogout'32         );33     }34 35 }

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

 

七. Eloquent 模型

  Eloquent ORM 以ActiveRecord形式来和数据库进行交互,拥有全部的数据表操作定义,单个模型实例对应数据表中的一行

1 $flights = App\Flight::where('active', 1)2                ->orderBy('name', 'desc')3                ->take(10)4                ->get();

  config/database.php中包含了模型的相关配置项。Eloquent 模型约定:

  1. 数据表名:模型以单数形式命名(CamelCase),对应的数据表为蛇形复数名(snake_cases),模型的$table属性也可用来指定自定义的数据表名称

  2. 主键:模型默认以id为主键且假定id是一个递增的整数值,也可以通过primaryKeyprimaryKey来自定义;如果主键非递增数字值,应设置incrementing = false

  3. 时间戳:模型会默认在你的数据库表有 created_at 和 updated_at 字段,设置timestamps=falsetimestamps=false可关闭模型自动维护这两个字段;dateFormat 属性用于在模型中设置自己的时间戳格式

  4. 数据库连接:模型默认会使用应用程序中配置的数据库连接,如果你想为模型指定不同的连接,可以使用 $connection 属性自定义

  5. 批量赋值:当用户通过 HTTP 请求传入了非预期的参数,并借助这些参数 create 方法更改了数据库中你并不打算要更改的字段,这时就会出现批量赋值(Mass-Assignment)漏洞,所以你需要先在模型上定义一个 fillable()fillable(白名单,允许批量赋值字段名数组)或guarded(黑名单,禁止批量赋值字段名数组)

    1 // 用属性取回航班,当结果不存在时创建它...2 $flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);3 4 // 用属性取回航班,当结果不存在时实例化一个新实例...5 $flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
  6. 模型软删除:如果模型有一个非空值 deleted_at,代表模型已经被软删除了。要在模型上启动软删除,则必须在模型上使用Illuminate\Database\Eloquent\SoftDeletes trait 并添加 deleted_at 字段到你的模型 $dates 属性上和数据表中,通过调用trashed方法可查询模型是否被软删除

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

     1 <?php 2  3 namespace App; 4  5 use Illuminate\Database\Eloquent\Model; 6 use Illuminate\Database\Eloquent\SoftDeletes; 7  8 class Flight extends Model 9 {10     use SoftDeletes;11 12     /**13      * 需要被转换成日期的属性。14      *15      * @var array16      */17     protected $dates = ['deleted_at'];18 }

    万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

    http://www.cnblogs.com/XiongMaoMengNan/p/6644892.html