路由

全局限制

如果你希望路由参数可以总是遵循正则表达式,则可以使用 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. zTree & ckeditor &ValidateCode.jar 使用个人心得总结

    zTree:依靠 jQuery 实现的多功能 “树插件”. 使用时只需要将下载的压缩包接用,复制里边的css 和 js 到指定目录即可. 如图所示: 在zTree的官网可以找到各种类型树的示例: 地址 ...

  2. 寒假day09

    今天看了论文的结构,定下了毕设论文的框架,刷了剑指offer的部分算法题.

  3. retrofit 上传文件 跟参数

    @Multipart @POST("postFied") Call<Void> postFied(@PartMap Map<String,String> m ...

  4. Coursera机器学习——Recommender System测验

    第一题本应该是基础题,考察Cost Function不同形式的表示方法,但却难住了我,说明基本概念掌握不够到位. 1. 在求和的部分,有两种可能,一种是(i,j)同时求和,即∑(i,j):r(i,j) ...

  5. 记录一次URL中有特殊字符怎么处理?

    你out了,赶紧换 RestTemplate 吧! 进入正题,直接实战!!! import java.util.HashMap; import java.util.Map; import org.ju ...

  6. memset的常见用法

    头文件 <cstring> 描述 因为memset函数按照字节填充,所以一般memset只能用来填充char型数组 ------------------------------------ ...

  7. 拉格朗日插值Python代码实现

    1. 数学原理 对某个多项式函数有已知的k+1个点,假设任意两个不同的都互不相同,那么应用拉格朗日插值公式所得到的拉格朗日插值多项式为: 其中每个lj(x)为拉格朗日基本多项式(或称插值基函数),其表 ...

  8. Codeforces 1294E - Obtain a Permutation

    题目大意: 给定一个n*m的矩阵 可以更改任意一个位置的值 也可以选择一整列全部往上移动一位,最上方的数移动到最下方 问最少操作多少次可以把这个矩阵移动成 1 2 3 ... m m+1 m+2 m+ ...

  9. ORB-SLAM2的编译运行以及TUM数据集测试

    ORB-SLAM2的编译运行以及TUM数据集测试 徐大徐 2018.02.06 17:04 字数 1838 阅读 2167评论 0喜欢 2 近段时间一直在学习高翔博士的<视觉SLAM十四讲> ...

  10. NOIpDairy

    Day 0 水水比赛 Day 1 写写Dp Part1:Dp基础练习 [HNOI2002]公交车路线 秒切,点数这么少,N这么大,目测O(N)+暴力更新 5min写完 P3842 [TJOI2007] ...