路由

全局限制

如果你希望路由参数可以总是遵循正则表达式,则可以使用 pattern 方法。你应该在 RouteServiceProvider 的 boot 方法里定义这些模式:

1
2
3
4
5
6
7
8
9
10
11
12
* 定义你的路由模型绑定,模式过滤器等。
*
* @param IlluminateRoutingRouter $router
* @return void
*/
public function (Router $router)
{
$router->pattern('id', '[0-9]+');
parent::boot($router);
}

模式一旦被定义,便会自动应用到所有使用该参数名称的路由上:

1
2
3
Route::get('user/{id}', function ($id) {
});

路由模型绑定

Laravel 路由模型绑定提供了一个方便的方式来注入类实例到你的路由中。例如,除了注入一个用户的 ID,你也可以注入与指定 ID 相符的完整 User 类实例。

首先,使用路由的 model 方法为指定参数指定类。必须在 RouteServiceProvider::boot 方法中定义你的模型绑定:

绑定参数至模型

1
2
3
4
5
6
public function (Router $router)
{
parent::boot($router);
$router->model('user', 'AppUser');
}

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

1
2
3
$router->get('profile/{user}', function(AppUser $user) {
});

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

注意:如果符合的模型不存在于数据库中,就会自动抛出一个 404 异常。

如果你希望指定你自己的“不存在”行为,只需传递一个闭包作为 model 方法的第三个参数:

1
2
3
$router->model('user', 'AppUser', function() {
throw new NotFoundHttpException;
});

如果你希望使用你自己的解析逻辑,那么你必须使用 Route::bind 方法。你传递至 bind 方法的闭包会获取 URI 的部分值,且会返回你想注入至路由的类实例:

1
2
3
$router->bind('user', function($value) {
return AppUser::where('name', $value)->first();
});

响应

响应宏

如果你想要自定义可以在很多路由和控制器重复使用的响应,可以使用 IlluminateContractsRoutingResponseFactory 实现的方法 macro。

举个例子,来自 服务提供者的 boot 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
namespace AppProviders;
use IlluminateSupportServiceProvider;
use IlluminateContractsRoutingResponseFactory;
class ResponseMacroServiceProvider extends ServiceProvider
{
* 提供注册后运行的服务。
*
* @param ResponseFactory $factory
* @return void
*/
public function boot(ResponseFactory $factory)
{
$factory->macro('caps', function ($value) use ($factory) {
return $factory->make(strtoupper($value));
});
}
}

macro 函数第一个参数为宏名称,第二个参数为闭包函数。宏的闭包函数会在 ResponseFactory 的实现或者辅助函数 response 调用宏名称的时候被运行:

1
return response()->caps('foo');

视图

把数据共享给所有视图

有时候你可能需要共享一些数据给应用进程的所有渲染视图,这时可以通过使用视图 factory 的 share 方法来完成。通常情况下,你会把这些调用 share 方法的代码放在一个服务提供者的 boot 方法内。你可以选择直接写在 AppServiceProvider 或是自己生成一个不同的服务提供者来放置这些代码:

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
<?php
namespace AppProviders;
class AppServiceProvider extends ServiceProvider
{
/**
* 启动任何应用进程的服务。
*
* @return void
*/
public function boot()
{
view()->share('key', 'value');
}
/**
* 注册服务提供者。
*
* @return void
*/
public function register()
{
//
}
}

视图组件

视图组件就是在视图被渲染前,会被调用的闭包或类方法。如果你想在每次渲染某些视图时绑定数据,视图组件可以帮你把这样的进程逻辑都组织到同一个地方。

让我们在 服务提供者 内注册我们的视图组件。下面例子将使用 View 辅助函数来获取底层 IlluminateContractsViewFactory contract 实现。请注意,Laravel 没有默认的目录来放置视图组件。你可以随意把它们放到任何地方。举例来说,你可以创建一个 AppHttpViewComposers 目录:

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
27
28
29
30
31
32
33
34
35
36
<?php
use IlluminateSupportServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* 在容器内注册所有绑定。
*
* @return void
*/
public function boot()
{
// 使用对象型态的视图组件...
view()->composer(
'profile', 'AppHttpViewComposersProfileComposer'
);
// 使用闭包型态的视图组件...
view()->composer('dashboard', function ($view) {
});
}
/**
* 注册服务提供者。
*
* @return void
*/
public function register()
{
//
}
}

现在我们已经注册好了视图组件,在每次 profile 视图渲染的时候,ProfileComposer@compose 方法都将会被运行。接下来我们来看看这个视图组件类要如何定义:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
namespace AppHttpViewComposers;
use IlluminateContractsViewView;
use IlluminateUsersRepository as UserRepository;
class ProfileComposer
{
/**
* 用户对象的实例。
*
* @var UserRepository
*/
protected $users;
/**
* 创建一个新的个人数据视图组件。
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
// 所有依赖都会自动地被服务容器解析...
$this->users = $users;
}
/**
* 将数据绑定到视图。
*
* @param View $view
* @return void
*/
public function compose(View $view)
{
$view->with('count', $this->users->count());
}
}

在视图被渲染之前,视图组件的 compose 方法会被调用,并传入一个 IlluminateContractsViewView 实例。你可以使用 with 方法来把数据绑定到视图。

备注:所有的 视图组件 都会被服务容器所解析,因此你可以在视图组件的构造器、类型提示中注入所需的任何依赖。

在视图组件内使用通配符

你可以在 composer 方法的第一个参数中传递一个视图数组,来同时对多个视图附加同一个视图组件:

1
2
3
4
view()->composer(
['profile', 'dashboard'],
'AppHttpViewComposersMyViewComposer'
);

视图的 composer 方法可以接受 * 作为通配符,所以你可以对所有视图附加 composer。如下:

1
2
3
view()->composer('*', function ($view) {
//
});

视图创建者

视图 创建者 几乎和视图组件运作方式一样;只是视图创建者会在视图初始化后就立即运行,而不是像视图组件一样要一直等到视图即将被渲染完成时才会被运行。要注册一个创建者,只要使用 creator 方法即可:

1
view()->creator('profile', 'AppHttpViewCreatorsProfileCreator');

模板

服务注入

@inject 命令可以取出 Laravel 服务容器 中的服务。传递给 @inject 的第一个参数为置放该服务的变量名称,而第二个参数为你想要解析的服务的类或是接口的名称:

1
2
3
4
5
@inject('metrics', 'AppServicesMetricsService')
<div>
每月收入:{{ $metrics->monthlyRevenue() }}。
</div>

扩充 Blade

Blade 甚至允许你自定义命令,你可以使用 directive 方法注册命令。当 Blade 编译器遇到该命令时,它将会带参数调用提供的回调函数。

以下例子会创建一个把指定的 $var 格式化的 @datetime($var) 命令:

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
27
28
29
30
31
<?php
namespace AppProviders;
use Blade;
use IlluminateSupportServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* 运行服务注册后的启动进程。
*
* @return void
*/
public function boot()
{
Blade::directive('datetime', function($expression) {
return "<?php echo with{$expression}->format('m/d/Y H:i'); ?>";
});
}
/**
* 在容器注册绑定。
*
* @return void
*/
public function register()
{
//
}
}

如你所见,Laravel 的 with 辅助函数被用在这个命令中。with 辅助函数会简单地返回指定的对象或值,并允许使用便利的链式调用。最后此命令生成的 PHP 会是:

1
<?php echo with($var)->format('m/d/Y H:i'); ?>

laravel中用到的ServiceProvide的更多相关文章

  1. Laravel中用GuzzleHttp

    阅读数:14715 今天项目中用到GuzzleHttp,开始不知道怎么用,其实还是很简单的. 直接在项目根目录,输入以下命令 composer require guzzlehttp/guzzle 1 ...

  2. Laravel核心解读--HTTP内核

    Http Kernel Http Kernel是Laravel中用来串联框架的各个核心组件来网络请求的,简单的说只要是通过public/index.php来启动框架的都会用到Http Kernel,而 ...

  3. PHP 从另一个角度来分析 Laravel 框架的依赖注入功能

    从根本上说,依赖注入不是让对象创建一个依赖关系,也不是让工厂对象去创建对象,而是将所需的依赖变成一个外部对象,使之成为一个"某些人的问题” 你为"某些人的问题”注入了类的依赖关系. ...

  4. 关于在框架中使用curl的思考,以及,curl其实很好用

    初步猜想: 在接触到框架文档的第一阶段时,会觉得控制器调用模型就是一件很简单的事,tp中用D方法或者M方法来实例化模型,laravel中用命名空间来加载模型,CI中用$this->load-&g ...

  5. legend3---12、DB::table('user_questions')和UserQuestion查询的结果的格式不一样

    legend3---12.DB::table('user_questions')和UserQuestion查询的结果的格式不一样 一.总结 一句话总结: 推荐使用模型查找的方式,可以直接数组方式访问: ...

  6. Mac OSX编译安装php7.1.8

    laravel中用到ldap认证包,要求php7.0以上版本,而且安装Mews\Captcha包的时候 验证码无法显示 报错如下: Call to undefined function Interve ...

  7. 通过中看不中用的代码分析Ioc容器,依赖注入....

    /** * 通过生产拥有超能力的超人实例 来理解IOC容器 */ //超能力模组接口 interface SuperModuleInterface{ public function activate( ...

  8. Laravel 学习笔记 —— 神奇的服务容器 [转]

    容器,字面上理解就是装东西的东西.常见的变量.对象属性等都可以算是容器.一个容器能够装什么,全部取决于你对该容器的定义.当然,有这样一种容器,它存放的不是文本.数值,而是对象.对象的描述(类.接口)或 ...

  9. PhpStorm下Laravel代码智能提示

    phpstorm&Laravel PHPstorm是我见过的最好的PHP的IDE,前年用的时候就毫不犹豫的抛弃了zend studio :) ,Laravel是我用过最好的框架,除了做手游后台 ...

随机推荐

  1. .NET CORE 配置Swagger文档

    1.先通过NuGet安装Swashbuckle.AspNetCore ,支持.NET core,版本是4.0.1,以上版本好像有些功能不支持 2.startup文件里注入swagger,Configu ...

  2. Delphi流的操作_文件合并

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  3. 协程与异步IO

    协  程 协程,又称微线程,纤程. 协程的优势:              协程的特点在于是一个线程执行.              协程的最大优势是极高的执行效率,因为子程序切换不是线程切换,而是由 ...

  4. Halcon函数总结(一)

    Halcon函数总结: read_image( :Image :FileName : )  //读入图像 crop_part(Image : ImagePart :Row,Column,Width,H ...

  5. Codeforces Round #571 (Unrated for Div. 1+Div. 2)

    A 略 B 被删了,被这个假题搞自闭了,显然没做出来. C 开始莽了个NTT,后来发现会TLE,其实是个SB前缀和,对于这题,我无**说. #include<bits/stdc++.h> ...

  6. 19 docker 多机器通信

    1. 本章实验 2. 环境搭建 1.编写 Vagrantfile 并创建虚拟机 并虚拟机node1绑定外部 192.168.205.10:8888 node2绑定外部 192.168.205.10:9 ...

  7. winform程序常用图标网站及资源

    1.easyicon网站,免费下载 https://www.easyicon.net/ 2.findicons https://findicons.com/ 3.iconarchive http:// ...

  8. 同步nginx日志到s3 bulket

    1.此处用的是增量同步 #!/bin/bash rm -rf /var/log/nginx/access.log.*.* local_host="`hostname --i`" a ...

  9. [Typora ] LaTeX公式输入

    [Typora 笔记] 数学输入整理 1.希腊字母表 大写 md 小写 md \(A\) A \(\alpha\) \alpha \(B\) B \(\beta\) \beta \(\Gamma\) ...

  10. 洛谷 P1258 小车问题

    题目传送门 解题思路: 首先,每个人都要做一次车,而且两个人要同时到达,这样才能使总时间最短. 那么,我们设起点为A,终点为B,小车先带甲开到C点后甲下车走到B点,同时小车掉头与已经走到D点的乙相向而 ...