路由

全局限制

如果你希望路由参数可以总是遵循正则表达式,则可以使用 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. blueimp,预览遮罩范围控制

    blueimg gallery github地址:https://github.com/blueimp/Gallery/blob/master/README.md 使用前提,引用css和js < ...

  2. MST(最小生成树)——Prim算法——HDU 1879-继续畅通工程

    Prim算法很好理解,特别是学完了迪杰斯特拉算法之后,更加能理解Prim的算法思想 和迪杰斯特拉算法差不多,由于最后要形成连通图,故任意指定一个点,作为初始点,遍历所有点,以当前最小权值的点(和迪杰斯 ...

  3. JAVA课程设计——俄罗斯方块

    0.负责模块为可视化界面,技术栈为 (1)异常处理 (2)多线程 (3)文件存储 (4)Java swing 1.登陆界面 我的代码 import java.awt.Color; import jav ...

  4. UML-什么是GRASP?

    1.定义 GRASP:General Responsibility Assignment Software Pattern,即通用职责分配软件模式,使用职责进行OO设计的学习工具. 2.本书目标 1) ...

  5. ftp主动和被动模式区别

    转载自:http://www.west999.com/cms/wiki/server/2018-11-16/49417.html FTP是基于TCP的服务的,FTP不同之处在于FTP使用两个端口,一个 ...

  6. Thread--线程间通信--管道

    在Java语言中提供了各种各样的输入/输出流Stream,使我们能够方便的对数据进行操作,其中管道流是一种特殊的流,用于在不同线程间直接传送数据.一个线程发送数据到输出管道,另一个线程从输入管道中读数 ...

  7. gitlab命令详解

    http://www.ruanyifeng.com/blog/2014/06/git_remote.html

  8. 14)载入png图片

    1)之前在窗口中载入图片  一般都是bmp的  但是  我想从网上下一些图片,这些图片可能是png的 2)那么就有了下面的操作 3)png图片可以直接做成透明的. 4)首先是创建窗口的基本代码: #i ...

  9. Android通过包名打开第三方应用

    import android.content.ComponentName; import android.content.Context; import android.content.Intent; ...

  10. LeetCode——542. 01 矩阵

    给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 0 1 0 0 0 ...