介绍

关于LTS与非LTS的选择

从产品生命周期上去考虑:
● 如果是商业项目的话,要走稳定路线,建议选择 LTS 长期支持版,可以避免掉入「更新大黑洞」。
● 如果是个人项目的话,要走激进路线,推荐使用最新版的 Laravel,主要有两个理由:
a. 跟上技术的趋势,对保持个人竞争力很重要,如果你不想被时代淘汰的话;
b. 知道新框架的技术决策,即使你在开发 5.1 的应用也是非常有帮助,例如这个路由分割的讨论,Laravel 5.3 里已经有非常合理的解决方案,完全可以直接采用,但是如果你不知道 5.3 ,那你估计就会发明自己的车轮。
参考:https://phphub.org/topics/2595

看5.3英文文档!

看文档经验:开始应该全部扫描一下,有个大概了解吧!然后再按步骤来!切记不要陷入细节!

用自己下载的php7.0.10不行,怎么也打不开openssl,用wamp中的7.0.4能行。

关于php7.0.10,配置好环境变量后提示丢失VCRUNTIME140.DLL文件,点击安装之,然后按照教程。但是接下来安装composer并不成功啊,感觉OpenSSL并没有开启。重启之,然后php –version,提示在C:\php\ext找不到php_openssl.dll。按照该提示建立文件夹,然后拷贝入文件。成功!

为了让应用程序的速度获得提升,可以使用 Artisan 命令 config:cache 将所有的配置文件缓存到单个文件。通过此命令将所有的设置选项合并成一个文件,让框架能够更快速的加载。

为何没有 Models 目录?
许多初学者都会困惑 Laravel 为什么没有 models 目录,这是有意而为之的。因为 models 这个词对不同人而言有不同的含义,容易造成歧义,有些开发者认为应用的模型指的是业务逻辑,另外一些人则认为模型指的是与数据库的交互。

public 目录存放着 index.php 文件,此文件被视为 Laravel 的 HTTP 入口。此目录还包含了前端控制器和资源文件(图片、JavaScript、CSS,等等)。

storage/app/public 可以用来生成用户上传文件,作为公开磁盘使用。默认的 public 磁盘使用 local 驱动,并且存储文件至 storage/app/public 文件夹中。为了能公开访问,你需要创建 public/storage 文件夹,然后作为符号链接到 storage/app/public 文件夹,你可以使用 php artisan storage:link 来创建符号链接。

可以将 Console 和 Http 目录试想为提供 API 进入应用程序的「核心」。Console 目录包含你全部的 Artisan 命令,而Http 目录包含你的控制器、中间件和请求。

你的应用程序通过 config/app.php 配置文件中的 debug 设置选项来控制浏览器对错误的细节显示。默认情况下,此设置选项是参照于保存在 .env 文件的 APP_DEBUG 环境变量。
在开发的时候,你应该将 APP_DEBUG 环境变量设置为 true。在你的上线环境中,这个值应该永远为 false。

Monolog recognizes the following severity levels - from least severe to most severe: debug, info,notice, warning, error, critical, alert, emergency.

错误控制

The Report Method
The report method is used to log exceptions or send them to an external service like Bugsnag or Sentry.

The Render Method
The render method is responsible for converting a given exception into an HTTP response that should be sent back to the browser.By default, the exception is passed to the base class which generates a response for you. However, you are free to check the exception type or return your own custom response:

Custom HTTP Error Pages
For example, if you wish to customize the error page for 404 HTTP status codes, create a resources/views/errors/404.blade.php. This file will be served on all 404 errors generated by your application. The views within this directory should be named to match the HTTP status code they correspond to. The HttpException instance raised by the abort function will be passed to the view as an $exception variable.


核心概念

服务容器(Service Container):

The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection. Dependency injection is a fancy phrase that essentially means this: class dependencies are “injected” into the class via the constructor or, in some cases, “setter” methods.

Binding Interfaces To Implementations

A very powerful feature of the service container is its ability to bind an interface to a given implementation.

For example, let’s assume we have an EventPusher interface and a RedisEventPusher implementation. Once we have coded our RedisEventPusher implementation of this interface, we can register it with the service container like so:

$this->app->bind('App\Contracts\EventPusher','App\Services\RedisEventPusher'
);

This statement tells the container that it should inject the RedisEventPusher when a class needs an implementation of EventPusher. Now we can type-hint the EventPusher interface in a constructor, or any other location where dependencies are injected by the service container:

use App\Contracts\EventPusher;/*** Create a new class instance.** @param  EventPusher  $pusher* @return void*/
public function __construct(EventPusher $pusher)
{$this->pusher = $pusher;
}

Contextual Binding
Sometimes you may have two classes that utilize the same interface, but you wish to inject different implementations into each class.

For example, two controllers may depend on different implementations of the Illuminate\Contracts\Filesystem\Filesystem contract. Laravel provides a simple, fluent interface for defining this behavior:

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');});

Tagging
Occasionally, you may need to resolve all of a certain “category” of binding. For example, perhaps you are building a report aggregator that receives an array of many different Report interface implementations. After registering the Report implementations, you can assign them a tag using the tag method:

$this->app->bind('SpeedReport', function () {//
});$this->app->bind('MemoryReport', function () {//
});$this->app->tag(['SpeedReport', 'MemoryReport'], 'reports');

Once the services have been tagged, you may easily resolve them all via the tagged method:

$this->app->bind('ReportAggregator', function ($app) {return new ReportAggregator($app->tagged('reports'));
});

Automatic Injection

Alternatively, and importantly, you may simply “type-hint” the dependency in the constructor of a class that is resolved by the container, including controllers, event listeners, queue jobs, middleware, and more. In practice, this is how most of your objects should be resolved by the container.

For example, you may type-hint a repository defined by your application in a controller’s constructor. The repository will automatically be resolved and injected into the class:

<?phpnamespace App\Http\Controllers;use App\Users\Repository as UserRepository;class UserController extends Controller
{/*** The user repository instance.*/protected $users;/*** Create a new controller instance.** @param  UserRepository  $users* @return void*/public function __construct(UserRepository $users){$this->users = $users;}/*** Show the user with the given ID.** @param  int  $id* @return Response*/public function show($id){//}
}

服务提供者(Service Providers):

Service providers are the central place of all Laravel application bootstrapping. Your own application, as well as all of Laravel’s core services are bootstrapped via service providers.

But, what do we mean by “bootstrapped”? In general, we mean registering things, including registering service container bindings, event listeners, middleware, and even routes. Service providers are the central place to configure your application.

If you open the config/app.php file included with Laravel, you will see a providers array. These are all of the service provider classes that will be loaded for your application. Of course, many of these are “deferred” providers, meaning they will not be loaded on every request, but only when the services they provide are actually needed.

Writing Service Providers

The Registrer Method:

All service providers extend the Illuminate\Support\ServiceProvider class. Most service providers contain a register and a boot method. Within the register method, you should only bind things into the service container.

You should never attempt to register any event listeners, routes, or any other piece of functionality within the register method.Otherwise, you may accidentally use a service that is provided by a service provider which has not loaded yet.

The Boot Method
This method is called after all other service providers have been registered, meaning you have access to all other services that have been registered by the framework:

<?phpnamespace App\Providers;use Illuminate\Support\ServiceProvider;class ComposerServiceProvider extends ServiceProvider
{/*** Bootstrap any application services.** @return void*/public function boot(){view()->composer('view', function () {//});}
}

注册(Registering Providers):
在config/app.php中注册:
To register your provider, simply add it to the array:

'providers' => [// Other Service ProvidersApp\Providers\ComposerServiceProvider::class,
],

Facades:

Facades为应用程序的服务容器中可用的类提供了一个「静态」接口。Laravel 自带了许多的 facades,可以用来访问其几乎所有的服务。Laravel facades 就是服务容器里那些基类的「静态代理」,相比于传统的静态方法调用,facades 在提供更简洁且丰富的语法的同时,还有更好的可测试性和扩展性。

何时使用 Facades:

Facades 有很多的好处,它们提供了简单易记的语法让你使用 Laravel 的各种功能,你再也不需要记住长长的类名来实现注入或者手动去配置。还有,因为它们对于PHP动态方法的独特用法,测试起来就非常容易。

但是,在使用 facades 时,有些地方还是需要特别注意。使用 facades 最主要的风险就是会引起类的体积的膨胀

由于 facades 使用起来非常简单而且不需要注入,我们会不经意间在单个类中大量使用。不像是使用依赖注入,用得越多,构造方法会越长,在视觉上就会引起注意,提醒你这个类有点太庞大了。

所以,在使用 facades 时,要特别注意把类的体积控制在一个合理的范围。

Facades 工作原理:

在 Laravel 应用中,一个 facade 其实就是一个提供访问容器中对象功能的类。其中最核心的部件就是 Facade 类。不管是 Laravel 自带的,还是用户自定义的 Facades,都是继承了 Illuminate\Support\Facades\Facade 这个类。

Facade 类利用了 __callStatic() 这个魔术方法来延迟调用容器中的对象的方法。在下面的例子里,调用了 Laravel 缓存系统。在代码里,我们可能以为 Cache 这个类的静态方法 get 被调用了:

<?phpnamespace App\Http\Controllers;use Cache;
use App\Http\Controllers\Controller;class UserController extends Controller
{/*** Show the profile for the given user.** @param  int  $id* @return Response*/public function showProfile($id){$user = Cache::get('user:'.$id);return view('profile', ['user' => $user]);}
}

注意在代码的最上面,我们导入的是 Cache facade。这个 facade 其实是我们获取底层 Illuminate\Contracts\Cache\Factory 接口实现的一个代理。我们通过这个 facade 调用的任何方法,都会被传递到 Laravel 缓存服务的底层实例中。

如果我们看一下 Illuminate\Support\Facades\Cache 这个类,你会发现根本没有 get 这个静态方法:

class Cache extends Facade
{/*** Get the registered name of the component.** @return string*/protected static function getFacadeAccessor() { return 'cache'; }
}

其实,Cache facade 是继承了基类 Facade 并且定义了 getFacadeAccessor() 方法。这个方法的功能是返回服务容器中绑定的名字。

当用户调用 Cache facade 的静态方法时,Laravel 会解析到 cache 在服务容积里绑定的具体的那个实例对象,并且调用这个对象的相应方法(在这个例子里就是 get 方法)

Contracts:

Most applications will be fine regardless of whether you prefer facades or contracts. However, if you are building a package, you should strongly consider using contracts since they will be easier to test in a package context.

As long as you are keeping your class’ responsibilities focused, you will notice very few practical differences between using contracts and facades.大多数时候差不多。

However, you may still have several questions regarding contracts. For example, why use interfaces at all? Isn’t using interfaces more complicated? Let’s distil the reasons for using interfaces to the following headings: loose coupling and simplicity.(低耦合和简单)

高耦合:

<?phpnamespace App\Orders;class Repository
{/*** The cache instance.*/protected $cache;/*** Create a new repository instance.** @param  \SomePackage\Cache\Memcached  $cache* @return void*/public function __construct(\SomePackage\Cache\Memcached $cache){$this->cache = $cache;}/*** Retrieve an Order by ID.** @param  int  $id* @return Order*/public function find($id){if ($this->cache->has($id))    {//}}
}

Instead of this approach, we can improve our code by depending on a simple, vendor agnostic interface:

<?phpnamespace App\Orders;use Illuminate\Contracts\Cache\Repository as Cache;class Repository
{/*** The cache instance.*/protected $cache;/*** Create a new repository instance.** @param  Cache  $cache* @return void*/public function __construct(Cache $cache){$this->cache = $cache;}
}

Now the code is not coupled to any specific vendor, or even Laravel. Since the contracts package contains no implementation and no dependencies, you may easily write an alternative implementation of any given contract, allowing you to replace your cache implementation without modifying any of your cache consuming code.


HTTP路由

路由:

所有的 Laravel 路由都在 routes 目录中的路由文件中定义,这些文件都由框架自动加载。 routes/web.php 文件中定义你的 web 页面路由。这些路由都会应用 web 中间件组,其提供了诸如 Session 和 CSRF 保护等特性。定义在 routes/api.php 中的路由都是无状态的,并且会应用 api 中间件组。

大多数的应用,都是从 routes/web.php 文件开始定义路由。例如:

<?php/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| This file is where you may define all of the routes that are handled
| by your application. Just tell Laravel the URIs it should respond
| to using a Closure or controller method. Build something great!
|
*/Route::any('/', 'HomeController@index');Route::any('/goods/list', 'GoodsController@list');
Route::any('/goods/update', 'GoodsController@update');

我们可以注册路由来响应所有的 HTTP 方法:

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

在上面,是使用了 any 方法注册一个实现响应所有 HTTP 的请求的路由。

CSRF 保护

任何指向 web 中 POST, PUT 或 DELETE 路由的 HTML 表单请求都应该包含一个 CSRF 令牌,否则,这个请求将会被拒绝。

必选路由参数:

有时我们需要在路由中捕获一些 URL 片段。例如,我们需要从 URL 中捕获用户的 ID ,我们可以这样定义路由参数:

Route::get('user/{id}', function ($id) {return 'User '.$id;
});

路由的参数通常都会被放在 {} 内,并且参数名只能为字母,当运行路由时,参数会通过路由闭包来传递。注意: 路由参数不能包含 - 字符。请用下划线 (_) 替换。

可选路由参数
当需要指定一个路由参数为可选时,可以在参数后面加上 ? 来实现,但是相应的变量必须有默认值:

Route::get('user/{name?}', function ($name = null) {return $name;
});Route::get('user/{name?}', function ($name = 'John') {return $name;
});

路由模型绑定

当注入模型 ID 到路由控制器时,我们通常需要查询这个 ID 对应的模型,Laravel 路由模型绑定提供了一个方便的方法自动将模型注入到我们的路由中,例如,除了注入一个用户的 ID,你也可以注入与指定 ID 相符的完整 User 类实例。

1.隐式绑定:
Laravel 会自动解析定义在路由或控制器动作(变量名匹配路由片段)中的 Eloquent 模型类型声明,例如:

Route::get('api/users/{user}', function (App\User $user) {return $user->email;
});

在这个例子中,由于类型声明了 Eloquent 模型 App\User,对应的变量名 $user 会匹配路由片段中的 {user},这样,Laravel 会自动注入与请求 URI 中传入的 ID 对应的用户模型实例。

如果数据库中找不到对应的模型实例,将会自动生成产生一个 404 HTTP 响应。

2.显式绑定:
可以使用 router 的 model 方法来注册显式绑定。你应该在 RouteServiceProvider 类中的 boot 方法内定义这些显式绑定:

public function boot()
{parent::boot();Route::model('user', 'App\User');
}

接着,定义包含 {user} 参数的路由:

$router->get('profile/{user}', function(App\User $user) {//
});

因为我们已经绑定 {user} 参数至 App\User 模型,所以 User 实例会被注入至该路由。所以,举个例子,一个至 profile/1 的请求会注入 ID 为 1 的 User 实例。

获取当前路由信息
你可以使用 Route 上的 current, currentRouteName, and currentRouteAction 方法来访问处理当前输入请求的路由信息:

$route = Route::current();$name = Route::currentRouteName();$action = Route::currentRouteAction();

中间件

Middleware provide a convenient mechanism for filtering HTTP requests entering your application. For example, Laravel includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to the login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.(参见framework中的RedirectIfAuthenticated.php)

Of course, additional middleware can be written to perform a variety of tasks besides authentication. A CORS middleware might be responsible for adding the proper headers to all responses leaving your application. A logging middleware might log all incoming requests to your application.

There are several middleware included in the Laravel framework, including middleware for authentication and CSRF protection. All of these middleware are located in the app/Http/Middleware directory.

Defining Middleware

To create a new middleware, use the make:middleware Artisan command:

php artisan make:middleware CheckAge

This command will place a new CheckAge class within your app/Http/Middleware directory.

In this middleware, we will only allow access to the route if the supplied age is greater than 200. Otherwise, we will redirect the users back to the home URI.

<?phpnamespace App\Http\Middleware;use Closure;class CheckAge
{/*** Run the request filter.** @param  \Illuminate\Http\Request  $request* @param  \Closure  $next* @return mixed*/public function handle($request, Closure $next){if ($request->age <= 200) {return redirect('home');}return $next($request);}}

As you can see, if the given age is less than or equal to 200, the middleware will return an HTTP redirect to the client; otherwise, the request will be passed further into the application. To pass the request deeper into the application (allowing the middleware to “pass”), simply call the next callback with the request.

It’s best to envision middleware as a series of “layers” HTTP requests must pass through before they hit your application. Each layer can examine the request and even reject it entirely.

Before & After Middleware
Whether a middleware runs before or after a request depends on the middleware itself. For example, the following middleware would perform some task before the request is handled by the application:

<?phpnamespace App\Http\Middleware;use Closure;class BeforeMiddleware
{public function handle($request, Closure $next){// Perform action//在被application处理之前做一些事情return $next($request);}
}

However, this middleware would perform its task after the request is handled by the application:

<?phpnamespace App\Http\Middleware;use Closure;class AfterMiddleware
{public function handle($request, Closure $next){$response = $next($request);// Perform action//在被application处理之后做一些事情return $response;}
}

Registering Middleware(注册)

1.Global Middleware:If you want a middleware to run during every HTTP request to your application, simply list the middleware class in the middleware property of your app/Http/Kernel.php class.

2.Assigning Middleware To Routes:
If you would like to assign middleware to specific routes, you should first assign the middleware a key in your app/Http/Kernel.php file. By default, the routeMiddleware property of this class contains entries for the middleware included with Laravel.

To add your own, simply append it to this list and assign it a key of your choosing.

Once the middleware has been defined in the HTTP kernel, you may use the middleware method to assign middleware to a route:

Route::get('admin/profile', function () {//
})->middleware('auth');

You may also assign multiple middleware to the route:

Route::get('/', function () {//
})->middleware('first', 'second');

When assigning middleware, you may also pass the fully qualified class name:

use App\Http\Middleware\CheckAge;Route::get('admin/profile', function () {//
})->middleware(CheckAge::class);

3.Middleware Groups:

Sometimes you may want to group several middleware under a single key to make them easier to assign to routes. You may do this using the middlewareGroups property of your HTTP kernel.

Middleware groups may be assigned to routes and controller actions using the same syntax as individual middleware. Again, middleware groups simply make it more convenient to assign many middleware to a route at once:

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

Middleware Parameters(带参数)
Middleware can also receive additional parameters. For example, if your application needs to verify that the authenticated user has a given “role” before performing a given action, you could create a CheckRole middleware that receives a role name as an additional argument.

Additional middleware parameters will be passed to the middleware after the $next argument:

<?phpnamespace App\Http\Middleware;use Closure;class CheckRole
{/*** Handle the incoming request.** @param  \Illuminate\Http\Request  $request* @param  \Closure  $next* @param  string  $role* @return mixed*/public function handle($request, Closure $next, $role){if (! $request->user()->hasRole($role)) {// Redirect...}return $next($request);}}

Terminable Middleware:

Sometimes a middleware may need to do some work after the HTTP response has been sent to the browser. For example, the “session” middleware included with Laravel writes the session data to storage after the response has been sent to the browser. If you define a terminate method on your middleware, it will automatically be called after the response is sent to the browser.

<?phpnamespace Illuminate\Session\Middleware;use Closure;class StartSession
{public function handle($request, Closure $next){return $next($request);}public function terminate($request, $response){// Store the session data...}
}

控制器:

Instead of defining all of your request handling logic as Closures in route files, you may wish to organize this behavior using Controller classes.

Controllers can group related request handling logic into a single class. Controllers are stored in the app/Http/Controllers directory.

Basic Controllers:

Below is an example of a basic controller class. Note that the controller extends the base controller class included with Laravel. The base class provides a few convenience methods such as the middleware method, which may be used to attach middleware to controller actions:(注意:没有要求说必须继承自base class,但如果不继承就不会轻易得到convenience features,诸如middleware, validate, and dispatch methods)

<?phpnamespace App\Http\Controllers;use App\User;
use App\Http\Controllers\Controller;class UserController extends Controller
{/*** Show the profile for the given user.** @param  int  $id* @return Response*/public function show($id){return view('user.profile', ['user' => User::findOrFail($id)]);}
}

You can define a route to this controller action like so:

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

Now, when a request matches the specified route URI, the show method on the UserController class will be executed. Of course, the route parameters will also be passed to the method.

Controller Middleware
Middleware may be assigned to the controller’s routes in your route files:

Route::get('profile', 'UserController@show')->middleware('auth');

However, it is more convenient to specify middleware within your controller’s constructor.

Using the middleware method from your controller’s constructor, you may easily assign middleware to the controller’s action.

You may even restrict the middleware to only certain methods on the controller class:

class UserController extends Controller
{/*** Instantiate a new new controller instance.** @return void*/public function __construct(){$this->middleware('auth');$this->middleware('log')->only('index');$this->middleware('subscribed')->except('store');}
}

Resource Controllers

Laravel resource routing assigns the typical “CRUD” routes to a controller with a single line of code. For example, you may wish to create a controller that handles all HTTP requests for “photos” stored by your application. Using the make:controller Artisan command, we can quickly create such a controller:

php artisan make:controller PhotoController --resource

This command will generate a controller at app/Http/Controllers/PhotoController.php. The controller will contain a method for each of the available resource operations.

Next, you may register a resourceful route to the controller:

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

This single route declaration creates multiple routes to handle a variety of actions on the resource. The generated controller will already have methods stubbed for each of these actions, including notes informing you of the HTTP verbs and URIs they handle.

Since HTML forms can’t make PUT, PATCH, or DELETE requests, you will need to add a hidden _method field to spoof these HTTP verbs. The method_field helper can create this field for you:{{ method_field('PUT') }}

HTTP Requests:

Accessing The Request

To obtain an instance of the current HTTP request via dependency injection, you should type-hint the Illuminate\Http\Request class on your controller method. The incoming request instance will automatically be injected by the service container:

<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;class UserController extends Controller
{/*** Store a new user.** @param  Request  $request* @return Response*/public function store(Request $request){$name = $request->input('name');//}
}

**Dependency Injection & Route Parameters**: If your controller method is also expecting input from a route parameter you should list your route parameters after your other dependencies. For example, if your route is defined like so:

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

You may still type-hint the Illuminate\Http\Request and access your route parameter id by defining your controller method as follows:

<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;class UserController extends Controller
{/*** Update the specified user.** @param  Request  $request* @param  string  $id* @return Response*/public function update(Request $request, $id){//}
}

**a few of the most important methods below**: 1.The path method returns the request’s path information. So, if the incoming request is targeted at http://domain.com/foo/bar, the path method will return foo/bar:` uri=uri = request->path();` The is method allows you to verify that the incoming request path matches a given pattern. You may use the * character as a wildcard when utilizing this method:

if ($request->is('admin/*')) {//
}

2.To retrieve the full URL for the incoming request you may use the url or fullUrl methods. The url method will return the URL without the query string, while the fullUrl method includes the query string:

// Without Query String...
$url = $request->url();// With Query String...
$url = $request->fullUrl();

3.The method method will return the HTTP verb for the request. You may use the isMethod method to verify that the HTTP verb matches a given string:

$method = $request->method();if ($request->isMethod('post')) {//
}

HTTP Responses:

Creating Responses:

All routes and controllers should return a response to be sent back to the user’s browser.

Laravel provides several different ways to return responses. The most basic response is simply returning a string from a route or controller. The framework will automatically convert the string into a full HTTP response:

Route::get('/', function () {return 'Hello World';
});

In addition to returning strings from your routes and controllers, you may also return arrays. The framework will automatically convert the array into a JSON response(自动转换为JSON):

Route::get('/', function () {return [1, 2, 3];
});

Response Objects
Typically, you won’t just be returning simple strings or arrays from your route actions. Instead, you will be returning full Illuminate\Http\Response instances or views(Response或者views).
Returning a full Response instance allows you to customize the response’s HTTP status code and headers.例如:

Route::get('home', function () {return response('Hello World', 200)->header('Content-Type', 'text/plain');
});

Attaching Headers To Responses
Keep in mind that most response methods are chainable, allowing for the fluent construction of response instances. For example, you may use the header method to add a series of headers to the response before sending it back to the user:

return response($content)->header('Content-Type', $type)->header('X-Header-One', 'Header Value')->header('X-Header-Two', 'Header Value');

Or, you may use the withHeaders method to specify an array of headers to be added to the response:

return response($content)->withHeaders(['Content-Type' => $type,'X-Header-One' => 'Header Value','X-Header-Two' => 'Header Value',]);

Redirects(重定向):
Redirect responses are instances of the Illuminate\Http\RedirectResponse class, and contain the proper headers needed to redirect the user to another URL. There are several ways to generate a RedirectResponse instance. The simplest method is to use the global redirect helper:

Route::get('dashboard', function () {return redirect('home/dashboard');
});

Redirecting To Named Routes
When you call the redirect helper with no parameters, an instance of Illuminate\Routing\Redirector is returned, allowing you to call any method on the Redirector instance. For example, to generate a RedirectResponse to a named route, you may use the route method:

return redirect()->route('login');

If your route has parameters, you may pass them as the second argument to the route method:

// For a route with the following URI: profile/{id}return redirect()->route('profile', ['id' => 1]);

Redirecting To Controller Actions

You may also generate redirects to controller actions. To do so, pass the controller and action name to the action method. Remember, you do not need to specify the full namespace to the controller since Laravel’s RouteServiceProvider will automatically set the base controller namespace:

return
redirect()->action('HomeController@index');

If your controller route requires parameters, you may pass them as the second argument to the action method:

return
redirect()->action('UserController@profile', ['id' => 1]
);

Other Response Types

The response helper may be used to generate other types of response instances. When the response helper is called without arguments, an implementation of the Illuminate\Contracts\Routing\ResponseFactory contract is returned. This contract provides several helpful methods for generating responses.

1.View Responses:
If you need control over the response’s status and headers but also need to return a view as the response’s content, you should use the view method:

return
response()->view('hello', $data, 200)->header('Content-Type', $type);

2.JSON Responses:
The json method will automatically set the Content-Type header to application/json, as well as convert the given array to JSON using the json_encode PHP function:

return response()->json(['name' => 'Abigail','state' => 'CA'
]);

3.File Downloads:
The download method may be used to generate a response that forces the user’s browser to download the file at the given path. The download method accepts a file name as the second argument to the method, which will determine the file name that is seen by the user downloading the file. Finally, you may pass an array of HTTP headers as the third argument to the method:

return response()->download($pathToFile);return response()->download($pathToFile, $name, $headers);

4.File Responses:
The file method may be used to display a file, such as an image or PDF, directly in the user’s browser instead of initiating a download. This method accepts the path to the file as its first argument and an array of headers as its second argument:

return response()->file($pathToFile);return response()->file($pathToFile, $headers);

HTTP Session:

Since HTTP driven applications are stateless, sessions provide a way to store information about the user across multiple requests.

Configuration:

The session configuration file is stored at config/session.php. Be sure to review the options available to you in this file. By default, Laravel is configured to use the file session driver, which will work well for many applications. In production applications, you may consider using the memcached or redis drivers for even faster session performance.

The session driver configuration option defines where session data will be stored for each request. Laravel ships with several great drivers out of the box。

Driver Prerequisites
1.Database

When using the database session driver, you will need to create a table to contain the session items. Below is an example Schema declaration for the table(要先创建一个table):

Schema::create('sessions', function ($table) {$table->string('id')->unique();$table->integer('user_id')->nullable();$table->string('ip_address', 45)->nullable();$table->text('user_agent')->nullable();$table->text('payload');$table->integer('last_activity');
});

You may use the session:table Artisan command to generate this migration:

php artisan session:tablephp artisan migrate

2.Redis

Before using Redis sessions with Laravel, you will need to install the predis/predis package (~1.0) via Composer. You may configure your Redis connections in the database configuration file. In the session configuration file, the connection option may be used to specify which Redis connection is used by the session.

Using The Session:
There are two primary ways of working with session data in Laravel: 1.the global session helper and 2.via a Request instance. First, let’s look at accessing the session via a Request instance, which can be type-hinted on a controller method. Remember, controller method dependencies are automatically injected via the Laravel service container:
1.

<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;
use App\Http\Controllers\Controller;class UserController extends Controller
{/*** Show the profile for the given user.** @param  Request  $request* @param  int  $id* @return Response*/public function show(Request $request, $id){$value = $request->session()->get('key');//}
}

When you retrieve a value from the session, you may also pass a default value as the second argument to the get method. This default value will be returned if the specified key does not exist in the session. If you pass a Closure as the default value to the get method and the requested key does not exist, the Closure will be executed and its result returned:

$value = $request->session()->get('key', 'default');$value = $request->session()->get('key', function() {return 'default';
});

2.
You may also use the global session PHP function to retrieve and store data in the session. When the session helper is called with a single, string argument, it will return the value of that session key. When the helper is called with an array of key / value pairs, those values will be stored in the session:

Route::get('home', function () {// Retrieve a piece of data from the session...$value = session('key');// Specifying a default value...$value = session('key', 'default');// Store a piece of data in the session...session(['key' => 'value']);
});

另外:
1.Retrieving All Session Data:$data = $request->session()->all();

2.The has method returns true if the value is present and is not null:

if ($request->session()->has('users')) {//
}

3.To determine if a value is present in the session, even if its value is null, you may use the exists method. The exists method returns true if the value is present:

if ($request->session()->exists('users')) {//
}

Storing Data
To store data in the session, you will typically use the put method or the session helper:

// Via a request instance...
$request->session()->put('key', 'value');// Via the global helper...
session(['key' => 'value']);

Pushing To Array Session Values

The push method may be used to push a new value onto a session value that is an array. For example, if the user.teams key contains an array of team names, you may push a new value onto the array like so:

$request->session()->push('user.teams', 'developers');

The pull method will retrieve and delete an item from the session in a single statement:

$value = $request->session()->pull('key', 'default');

表单验证:

To learn about Laravel’s powerful validation features, let’s look at a complete example of validating a form and displaying the error messages back to the user.一个例子:
步骤:

1.Defining The Routes:

First, let’s assume we have the following routes defined in our routes/web.php file:

Route::get('post/create', 'PostController@create');Route::post('post', 'PostController@store');

Of course, the GET route will display a form for the user to create a new blog post, while the POST route will store the new blog post in the database.

2.Creating The Controller:
Next, let’s take a look at a simple controller that handles these routes. We’ll leave the store method empty for now:

<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;
use App\Http\Controllers\Controller;class PostController extends Controller
{/*** Show the form to create a new blog post.** @return Response*/public function create(){return view('post.create');}/*** Store a new blog post.** @param  Request  $request* @return Response*/public function store(Request $request){// Validate and store the blog post...}
}

3.Writing The Validation Logic:

Now we are ready to fill in our store method with the logic to validate the new blog post. If you examine your application’s base controller (App\Http\Controllers\Controller) class, you will see that the class uses a ValidatesRequests trait. This trait provides a convenient validate method to all of your controllers.

The validate method accepts an incoming HTTP request and a set of validation rules. If the validation rules pass, your code will keep executing normally; however, if validation fails, an exception will be thrown and the proper error response will automatically be sent back to the user. In the case of a traditional HTTP request, a redirect response will be generated, while a JSON response will be sent for AJAX requests.

To get a better understanding of the validate method, let’s jump back into the store method:

/*** Store a new blog post.** @param  Request  $request* @return Response*/
public function store(Request $request)
{$this->validate($request, ['title' => 'required|unique:posts|max:255','body' => 'required',]);// The blog post is valid, store in database...
}

As you can see, we simply pass the incoming HTTP request and desired validation rules into the validate method. Again, if the validation fails, the proper response will automatically be generated. If the validation passes, our controller will continue executing normally.


视图和模板

视图:

创建视图

视图的用途是用来存放应用程序中 HTML 内容,并且能够将你的控制器层(或应用逻辑层)与展现层分开。视图文件目录为 resources/views ,示例视图如下:

<!-- 此视图文件位置:resources/views/greeting.php --><html><body><h1>Hello, {{ $name }}</h1></body>
</html>

上述视图文件位置为 resources/views/greeting.php ,我们可以通过全局函数 view 来使用这个视图,如下:

Route::get('/', function () {return view('greeting', ['name' => 'James']);
});

如你所见,view 函数中,第一个参数即 resources/views 目录中视图文件的文件名,第二个参数是一个数组,数组中的数据可以直接在视图文件中使用。在上面示例中,我们将 name 变量传递到了视图中,并在视图中使用 Blade 模板语言 打印出来。

当然,视图文件也可能存放在 resources/views 的子目录中,你可以使用英文句点 . 来引用深层子目录中的视图文件。例如,一个视图的位置为 resources/views/admin/profile.php ,使用示例如下:

return view('admin.profile', $data);

把数据共享给所有视图:
有时候可能需要共享特定的数据给应用程序中所有的视图,那这时候你需要 View Facade 的 share 方法。通常需要将所有 share 方法的调用代码放到 服务提供者 的 boot 方法中,此时你可以选择使用 AppServiceProvider 或创建独立的 服务提供者 。

视图合成器:

视图合成器是在视图渲染时调用的一些回调或者类方法。如果你需要在某些视图渲染时绑定一些数据上去,那么视图合成器就是你的的不二之选,另外他还可以帮你将这些绑定逻辑整理到特定的位置。

下面例子中,我们会在一个 服务提供者 中注册一些视图合成器。同时使用 View Facade 来访问 Illuminate\Contracts\View\Factory contract 的底层实现。注意:Laravel 没有存放视图合成器的默认目录,但你可以根据自己的喜好来重新组织,例如:App\Http\ViewComposers。

<?phpnamespace App\Providers;use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;class ComposerServiceProvider extends ServiceProvider
{/*** Register bindings in the container.** @return void*/public function boot(){// Using class based composers...View::composer('profile', 'App\Http\ViewComposers\ProfileComposer');// Using Closure based composers...View::composer('dashboard', function ($view) {//});}/*** Register the service provider.** @return void*/public function register(){//}
}

到此我们已经注册了上面的视图合成器,效果是每次 profile 视图渲染时,都会执行 ProfileComposer@compose 方法。那么下面我们来定义这个合成器类吧。

<?phpnamespace App\Http\ViewComposers;use Illuminate\View\View;
use App\Repositories\UserRepository;class ProfileComposer
{/*** The user repository implementation.** @var UserRepository*/protected $users;/*** Create a new profile composer.** @param  UserRepository  $users* @return void*/public function __construct(UserRepository $users){// Dependencies automatically resolved by service container...$this->users = $users;}/*** Bind data to the view.** @param  View  $view* @return void*/public function compose(View $view){$view->with('count', $this->users->count());}
}

每当视图渲染时,该合成器的 compose 方法都会被调用,并且传入一个 Illuminate\View\View 实例作为参数,在这个过程中,你可以使用 with 方法绑定数据到目标视图。

将视图合成器附加到多个视图:
composer 方法同时也接受通配符 * ,可以让你将一个视图合成器一次性绑定到所有的视图。

//多个
View::composer(['profile', 'dashboard'],'App\Http\ViewComposers\MyViewComposer'
);
//全部
View::composer('*', function ($view) {//
});

Blade 模板:

Blade 是 Laravel 提供的一个既简单又强大的模板引擎。和其他流行的 PHP 模板引擎不一样,Blade 并不限制你在视图中使用原生 PHP 代码。所有 Blade 视图文件都将被编译成原生的 PHP 代码并缓存起来,除非它被修改,否则不会重新编译,这就意味着 Blade 基本上不会给你的应用增加任何额外负担。Blade 视图文件使用 .blade.php 扩展名,一般被存放在 resources/views 目录。

模板继承:

定义页面布局:

Blade 的两个主要优点是模板继承区块
为方便开始,让我们先通过一个简单的例子来上手。首先,我们需要确认一个 “master” 的页面布局。因为大多数 web 应用是在不同的页面中使用相同的布局方式,我们可以很方便的定义这个 Blade 布局视图:

<!-- 文件保存于 resources/views/layouts/app.blade.php --><html><head><title>应用程序名称 - @yield('title')</title></head><body>@section('sidebar')这是 master 的侧边栏。@show<div class="container">@yield('content')</div></body>
</html>

@section 命令正如其名字所暗示的一样是用来定义一个视图区块的,而 @yield 指令是用来显示指定区块的内容的。

继承页面布局:

当定义子页面时,你可以使用 Blade 提供的 @extends 命令来为子页面指定其所 「继承」 的页面布局。 当视图 @section Blade 的布局之后,即可使用 @section 命令将内容注入于布局的区块中。切记,在上面的例子里,布局中使用 @yield 的地方将会显示这些区块中的内容:

//注意跟上面的父类进行比较
<!-- Stored in resources/views/child.blade.php -->@extends('layouts.app')@section('title', 'Page Title')@section('sidebar')@parent<p>This is appended to the master sidebar.</p>
@endsection@section('content')<p>This is my body content.</p>
@endsection

在上面的例子里,sidebar 区块利用了@parent命令追加布局中的 sidebar 区块中的内容,如果不使用则会覆盖掉布局中的这部分内容。@parent命令会在视图被渲染时替换为布局中的内容。

当然,可以通过在路由中使用全局辅助函数 view 来返回 Blade 视图:

Route::get('blade', function () {return view('child');
});

显示数据:
你可以使用 「中括号」 包住变量以显示传递至 Blade 视图的数据。如下面的路由设置:

Route::get('greeting', function () {return view('welcome', ['name' => 'Samantha']);
});

你可以像这样显示 name 变量的内容:

Hello, {{ $name }}.

当然也不是说一定只能显示传递至视图的变量内容。你也可以显示 PHP 函数的结果。事实上,你可以在 Blade 中显示任意的 PHP 代码

The current UNIX timestamp is {{ time() }}.

本土化:

Laravel 的本地化功能提供方便的方法来获取多语言的字符串,让你的网站可以简单的支持多语言。

语言包存放在 resources/lang 目录下的文件里。在此目录中应该有应用对应支持的语言并将其对应到每一个子目录:

/resources/lang/enmessages.php/esmessages.php

语言包简单地返回键值和字符串数组,例如:

<?phpreturn ['welcome' => 'Welcome to our application'
];

应用的默认语言保存在 config/app.php 配置文件中。你也可以设置 「备用语言」 ,它将会在当现有语言没有指定语句时被使用。例如:

'locale' => 'zh',
'fallback_locale' => 'en',

JavaScript 与 CSS

Laravel 并没有规定你使用哪个 JavaScript 或 CSS 预处理器,不过默认提供了对大多数应用都很适用的 BootstrapVue 来作为起点。 Laravel 默认使用 NPM 安装这些前端的依赖。

编写 CSS:
在 Laravel 的根目录中的 Package.json 文件引入了 bootstrap-sass 依赖包可以帮助你使用 Bootstrap 制作应用程序的前端原型。不过,你可以根据自己应用程序的需要在 package.json 灵活的添加或者移除依赖包。使用 Bootstrap 框架来构建你的 Laravel 应用程序并不是必选项,它只是给那些想用它的人提供一个很好的起点。

编写 JavaScript:
在项目根目录中的 package.json 可以找到应用程序的所有 JavaScript 依赖。它和 composer.json 文件类似,不同的是它指定的是 JavaScript 的依赖而不是 PHP 的依赖。


数据库

入门:

Laravel 支持四种类型的数据库:
1.MySQL
2.Postgres
3.SQLite
4.SQL Server

配置mysql:

//Default Database Connection Name
'default' => env('DB_CONNECTION', 'mysql'),'mysql' => ['driver' => 'mysql','host' => env('DB_HOST', 'localhost'),'port' => env('DB_PORT', '3306'),'database' => env('DB_DATABASE', 'forge'),'username' => env('DB_USERNAME', 'forge'),'password' => env('DB_PASSWORD', ''),'charset' => 'utf8','collation' => 'utf8_general_ci','prefix' => '','strict' => true,'engine' => null,],

数据库读写分离:
有时候你希望把一个数据库作为只读数据库,而另一个数据库则负责写入、更新以及删除。Laravel 会让你轻而易举的实现,并适用于原始查找、查询语句构造器或是 Eloquent ORM。例如:

'mysql' => ['read' => ['host' => '192.168.1.1',],'write' => ['host' => '196.168.1.2'],'driver'    => 'mysql','database'  => 'database','username'  => 'root','password'  => '','charset'   => 'utf8','collation' => 'utf8_unicode_ci','prefix'    => '',
],

注意,有两个键加入了这个配置文件数组内: readwrite 。 它们两个都是一个数组且只包含了一个键: host 。 而 read 和 write 连接的其他配置都包含在 mysql 数组中。

所以,如果需要在主要的数组内重写值,只需在 read and write 数组内放置设置参数即可。在这个例子中, 192.168.1.1 将会只提供数据读取数据的功能,而 192.168.1.2 提供数据库写入。数据库的凭证、前缀、编码设置,以及所有其它的选项都被存放在 mysql 数组内,这两个连接将会共用这些选项

使用多数据库连接:

当使用多个数据连接时,你可以使用 DB facade 的 connection 方法。在 config/database.php 中定义好的数据库连接 name 作为 connection 的参数进行传递。

$users = DB::connection('foo')->select(...);

运行原生 SQL 语句

配置好数据库连接以后,你可以使用 DB facade 来执行查询。 DB facade 提供了 selectupdateinsertdeletestatement 的查询方法。

比如select:

$users = DB::select('select * from users where active = ?', [1]);//select 方法以数组的形式返回结果集,数组中的每一个结果
//都是一个**PHP StdClass 对象**
//可以像下面这样访问foreach ($users as $user) {echo $user->name;
}

运行一般声明(statement):

DB::statement('drop table users');

监听查询事件

如果你希望能够监控到程序执行的每一条 SQL 语句,那么你可以使用 listen 方法。 该方法对查询日志调试非常有用, 你可以在 服务容器 中注册该方法:

public function boot(){DB::listen(function ($query) {// $query->sql// $query->bindings// $query->time});}

数据库事务

想要在一个数据库事务中运行一连串操作,可以使用 DB facade 的 transaction 方法。如果在事务的 Closure 中抛出了异常,那么事务会自动的执行回滚操作。如果 Closure 成功的执行,那么事务就会自动的进行提交操作。你不需要在使用 transaction 方法时考虑手动执行回滚或者提交操作:

DB::transaction(function () {DB::table('users')->update(['votes' => 1]);DB::table('posts')->delete();
});

手动操作事务:
1.手动开始一个事务的回滚和提交操作DB::beginTransaction();
2.回滚事务DB::rollBack();
3.提交事务DB::commit();

数据库:查询构造器:

关于“增删查改”等的各种语法请直接移步:
https://doc.laravel-china.org/docs/5.3/queries

关于悲观锁定
查询语句构造器也包含一些可用以协助你在 select 语法上作「悲观锁定」的函数。若要以「共享锁」来运行语句,则可在查找上使用 sharedLock 方法。共享锁可避免选择的数据列被更改,直到事务被提交为止:

DB::table('users')->where('votes', '>', 100)->sharedLock()->get();

此外,你也可以使用 lockForUpdate 方法。「用以更新」锁可避免数据列被其它共享锁修改或选取:

DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();

分页:

Customizing The Paginator URI:

The setPath method allows you to customize the URI used by the paginator when generating links. For example, if you want the paginator to generate links like http://example.com/custom/url?page=N, you should pass custom/url to the setPath method:

Route::get('users', function () {$users = App\User::paginate(15);$users->setPath('custom/url');//
});

Converting Results To JSON:

The Laravel paginator result classes implement the Illuminate\Contracts\Support\Jsonable Interface contract and expose the toJson method, so it’s very easy to convert your pagination results to JSON. You may also convert a paginator instance to JSON by simply returning it from a route or controller action:

Route::get('users', function () {return App\User::paginate();
});

The JSON from the paginator will include meta information such as total, current_page, last_page, and more. The actual result objects will be available via the data key in the JSON array. Here is an example of the JSON created by returning a paginator instance from a route:

{"total": 50,"per_page": 15,"current_page": 1,"last_page": 4,"next_page_url": "http://laravel.app?page=2","prev_page_url": null,"from": 1,"to": 15,"data":[{// Result Object},{// Result Object}]
}

Customizing The Pagination View:
By default, the views rendered to display the pagination links are compatible with the Bootstrap CSS framework. However, if you are not using Bootstrap, you are free to define your own views to render these links. When calling the links method on a paginator instance, pass the view name as the first argument to the method:

{{ $paginator->links('view.name') }}

数据库迁移:

Migrations are like version control for your database, allowing your team to easily modify and share the application’s database schema. Migrations are typically paired with Laravel’s schema builder to easily build your application’s database schema. If you have ever had to tell a teammate to manually add a column to their local database schema, you’ve faced the problem that database migrations solve.

数据库: 数据填充:

Laravel 可以简单的使用 seed 类来给数据库填充测试数据。所有的 seed 类都放在 database/seeds 目录下。你可以任意地为 Seed 类命名,但是应该遵守某些大小写规范,可用类似 UserTableSeeder 之类的命名。 Laravle 默认为你定义了一个 DatabaseSeeder 类。你可以在这个类中使用 call 方法来运行其它的 seed 类,以借此控制数据填充的顺序

在自定义的 seeder 类里只有一个默认方法:run。你可以在 run 方法中给数据库添加任何数据。你可使用 查询语句构造器 或 Eloquent 模型工厂 来手动添加数据。例如:

<?phpuse Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;class DatabaseSeeder extends Seeder
{/*** 运行数据库填充。** @return void*/public function run(){DB::table('users')->insert(['name' => str_random(10),'email' => str_random(10).'@gmail.com','password' => bcrypt('secret'),]);}
}

使用模型工厂:
手动为每一个 seed 模型一一指定属性是很麻烦的一件事。作为替代方案,你可以使用 模型工厂 来帮助你更便捷的生成大量数据库数据。首先,阅读 模型工厂的文档 来学习如何定义你的工厂。一旦工厂被定义,就能使用 factory 这个辅助函数函数来添加数据到数据库。

让我们来创建 50 个用户并为每个用户创建一个关联:

/*** 运行数据库填充。** @return void*/
public function run()
{factory(App\User::class, 50)->create()->each(function($u) {$u->posts()->save(factory(App\Post::class)->make());});
}

Redis:

参考:
https://doc.laravel-china.org/docs/5.3/redis


综合话题

事件:

Laravel 事件机制实现了一个简单的观察者模式,来订阅和监听在应用中出现的各种事件,事件类通常被保存在 app/Events 目录下,而它们的监听器被保存在 app/Listeners 目录下。如果你在应用中看不到这些文件夹也不要担心,当你用 Artisan 命令来生成事件和监听器的时候他们就会被创建了。

事件机制是一种很好的应用解耦方式,因为一个事件可以拥有多个互不依赖的监听器。举例来说,每次你把用户的订单发完货后都会希望给他发个 Slack 通知。这时候你就可以发起一个 OrderShipped 事件,它会被对应的监听器接收到再传递给 Slack 通知模块,这样你就不用把订单处理的代码跟 Slack 通知的代码耦合在一起了。

注册事件和监听器:

包含在你 Laravel 应用中的 EventServiceProvider 提供了一个很方便的地方来注册所有的事件监听器。listen 属性是一个数组,它包含了所有事件(键)以及事件对应的监听器(值)。你也可以根据应用需求来增加事件到这个数组,例如,我们增加一个 OrderShipped 事件:

/*** 应用程序的事件监听器映射。** @var array*/
protected $listen = ['App\Events\OrderShipped' => ['App\Listeners\SendShipmentNotification',],
];

生成事件和监听器:
手动创建事件和监听器是很麻烦的,简单的方式是,在 EventServiceProvider 中写上事件和监听器然后使用 event:generate 命令。这个命令会自动生成在 EventServiceProvider 中列出的所有事件和监听器,当然已经存在的事件和监听器将保持不变:php artisan event:generate

定义事件

一个事件类是包含了相关事件信息的数据容器。例如,假设我们生成的 OrderShipped 事件接收一个 Eloquent ORM 对象:

<?phpnamespace App\Events;use App\Order;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;class OrderShipped extends Event
{use SerializesModels;public $order;/*** 创建一个事件实例** @param  Order  $order* @return void*/public function __construct(Order $order){$this->order = $order;}
}

正如你所见的,这个事件类没有包含其它逻辑。它只是一个被购买的 Order 对象的容器。如果事件对象是使用 PHP 的 serialized 函数进行序列化,那么事件所使用的 SerializesModels trait 将会优雅的序列化任何的 Eloquent 模型。

定义监听器
接下来,让我们看一下例子中事件的监听器。事件监听器的 handle 方法接收了事件实例。event:generate 命令将会在事件的 handle 方法中自动加载正确的事件类和类型提示。在 handle 方法内,你可以运行任何需要响应该事件的业务逻辑。

<?phpnamespace App\Listeners;use App\Events\OrderShipped;class SendShipmentNotification
{/*** 创建事件监听器。** @return void*/public function __construct(){//}/*** 处理事件。** @param  OrderShipped  $event* @return void*/public function handle(OrderShipped $event){// 使用 $event->order 来访问 order ...}
}

Laravel文档整理相关推荐

  1. 将Html文档整理为规范XML文档

    有多种方式可以在.NET 平台进行HTML文件解析.数据提取,其中最简单.稳妥的办法是先使用工具将Html文档整理成XML文档,再通过XML Dom模型或XPath灵活地进行数据处理.SGML便是一个 ...

  2. django+nginx+uwsgi项目部署文档整理

    django+nginx+uwsgi项目部署文档整理 参考文章:https://blog.csdn.net/qq_42314550/article/details/81805328 一.python安 ...

  3. NodeJS-001-Nodejs学习文档整理(转-出自http://www.cnblogs.com/xucheng)

    Nodejs学习文档整理 http://www.cnblogs.com/xucheng/p/3988835.html 1.nodejs是什么: nodejs是一个是javascript能在后台运行的平 ...

  4. Laravel文档梳理6、响应

    前言:Laravel文档梳理,仅作为记录后看,无关其他. 1.laravel框架最基本的响应 Route::get('/', function () {     return 'Hello World ...

  5. 2503平台GPS MT3333秒定参考文档整理 - MTK物联网在线解答 - 技术论坛

        2503平台GPS MT3333秒定参考文档整理 [DESCRIPTION] 以下是目前整理的给客户参考的2503秒定测试及GPS介绍的文档,其中均可在DCC上下载. [SOLUTION] 2 ...

  6. 韩顺平php可爱屋源码_韩顺平_php从入门到精通_视频教程_第20讲_仿sohu主页面布局_可爱屋首页面_学习笔记_源代码图解_PPT文档整理...

    韩顺平_php从入门到精通_视频教程_第20讲_仿sohu首页面布局_可爱屋首页面_学习笔记_源代码图解_PPT文档整理 对sohu页面的分析 注释很重要 经验:写一点,测试一点,这是一个很好的方法. ...

  7. Android 学习文档整理收集

    利用闲暇时间整理了一份 Android 学习文档整理收集,希望能够对大家有所帮助,也欢迎各位帮忙补充. Android Android基础入门教程 CSDN主题Android专栏 极客头条Androi ...

  8. VIM快速文档整理技巧

    VIM整理文档具有非常好的效果,我最近由于开发的需要,在网上收集了大量有关中中医的文章,需要整理优化调整成需要的格式,存入数据库中供前端调用.使用过WORD,excel等工具都不尽如意,后来使用VIM ...

  9. python文档整理,Python官方文档内置函数整理Word版

    <Python官方文档内置函数整理Word版>由会员分享,可在线阅读,更多相关<Python官方文档内置函数整理Word版(6页珍藏版)>请在人人文库网上搜索. 1.传播优秀W ...

  10. EasyClick 文档整理

    EasyClick 开发文档整理 个人整理的部分 EasyClick JavaScript基础教程 EasyClick 开发文档–函数篇 EasyClick 开发文档–UI篇 EasyClick 开发 ...

最新文章

  1. Nacos配置中心原理
  2. hue集成hbase出现TSocket read 0 bytes
  3. linux使用遇到的一些小问题
  4. nyoj - 947(Max Xor)字典树
  5. 【机器学习】NMF(非负矩阵分解)
  6. nb模块不能接收公网消息_物联网连接技术之NB-IOT无线技术介绍
  7. 09_期望极大法EM2_统计学习方法
  8. bzoj 2959: 长跑【LCT+并查集】
  9. 拓端tecdat|R语言非线性回归nls探索分析河流阶段性流量数据和评级曲线、流量预测可视化
  10. 在python中使用autoit_Python + Selenium + AutoIt 模拟键盘实现另存为、上传、下载操作详解...
  11. 使用pure-ftpd快速部署FTP服务
  12. java自动装箱|拆箱解密
  13. idea卸载不干净怎么办_Office卸载不干净怎么办?我想你一定需要Mac卸载Office的图文教程!...
  14. ROS:bag数据包内容提取——雷达点云数据和imu数据
  15. 5款实用又有趣的微信小程序,每一款都是大家公认的好用!
  16. 【C++/嵌入式笔试面试八股】大纲介绍
  17. 【JavaScript实现十进制转换成二进制】
  18. 文件夹选择框 文件选择框
  19. 学习累了休息一下——————看完不笑你厉害
  20. jquery.validate.min.js使用介绍

热门文章

  1. 判断手机横屏竖屏,切换时刷新一次页面
  2. 2022年10月总结 (距离激动人心的928已经过去一个多月了)
  3. 邮箱服务器如何配置?POP和IMAP如何定义?
  4. 硅谷华人码农成语大全
  5. Docker 占用磁盘空间清理
  6. 解决局域网文件共享“****无法复制,指定的网络名不可用”
  7. 大数据查询怎么优化?
  8. javac编译带有package的java文件
  9. node.js接入微信公众号开发
  10. 智能陈桥五笔7.8试用编号是多少_学霸的学习方法,听多少都不嫌多