路由

全局限制

如果你希望路由参数可以总是遵循正则表达式,则可以使用 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. Freemarker的一点延生

    1.freemarker一般不是单独使用,他可以和activeMQ互相结合,来完成功能的. 使用它有 几点好处, 首先就是提高程序效率,一般情况我们的页面都是jsp,而jsp实际上是servlet,在 ...

  2. Windows下MariaDB数据搬家问题

    背景:公司买了一台服务器要将原来老服务器数据库数据导入新的服务器上,两台服务器环境如下 做好准备后开始实施,老数据库进行停库 找到MariaDB的安装目录下的整data目录进行拷贝,然后到新服务器进行 ...

  3. OpenMP笔记(五)

    任务调度主要用于并行的for循环中,当循环中每次迭代的计算量不相等时,如果简单地给各个线程分配相同次数的迭代的话,会造成各个线程计算负载不均衡,这会使得有些线程先执行完,有些后执行完,造成某些CPU核 ...

  4. R语言入门 (有其他编程语言基础)

    慢慢才意识到概率统计的重要性,当时学的时候只知道很重要,是机器学习基础啥的,但是却没有真正意识到( ╯□╰ ).我现在的理解是,统计学习可以从大数据中挖掘出规律(其实和数据挖掘还是很相关的),在科研工 ...

  5. uploadify ASP.net 使用笔记

    <script type="text/javascript" src="jquery.uploadify.min.js"></script & ...

  6. java求两个圆相交坐标

    最近由于项目需要,根据两个圆函数求出相交的坐标.实现代码如下,另感谢两圆求交点算法实现Java代码,虽然他所贡献的代码中存在问题,但仍有借鉴意义. 1.两个圆相交的数学求法 在中学数学中我们知道,一个 ...

  7. Oracle与MySQL的区别对比

    本文对数据库Oracle与MySQL进行了区别对比,其中从并发性.一致性.事务.数据持久性等十三方面进行了对比. 本文摘自 51cto 一.并发性 并发性是oltp数据库最重要的特性,但并发涉及到资源 ...

  8. LGOJ1344 追查坏牛奶

    Description link 题意概述:给一张图,每条边有边权,求让点 \(1\) 和点 \(n\) 不连通的"最小破坏边权和" 和 "在此基础上的最小破坏边数&qu ...

  9. netty 百度网盘 密码

    netty基础 https://pan.baidu.com/s/1v_ME49LIef1Kwga8z2QbDw?spm=a1z09.2.0.0.680b2e8d5LI8S0   zb7u mina n ...

  10. JavaEE--分布式与集群

    参考:https://www.zhihu.com/question/20004877 集群是个物理形态,分布式是个工作方式. 只要是一堆机器,就可以叫集群,他们是不是一起协作着干活,这个谁也不知道:一 ...