When developing applications with Laravel, you may sometimes wonder where to put “stuff”. For example, where should you put “helper” functions? Where should you put event listeners? Where should you put view composers? It may be surprising for you to know that the answer is: “wherever you want!” Laravel does not have many conventions regarding where things belong on the file system. However, as this answer is not often satisfactory, we'll explore some possible locations for such things before moving on.
当用Laravel开发应用时,你可能迷惑于应该把各种“东西”都放在哪儿。比如,辅助函数要放在哪里?事件监听器要放在哪里?视图组件要放在哪里?答案可能出乎你的意料——“想放哪儿都行!”Laravel并没有很多在文件系统上的约定。不过这个答案的确不能让人满意,所以下面我们就这个问题展开探索,探索这些“东西”究竟可以放在哪儿。
Laravel ships with a file full of helpers functions (support/helpers.php
). You may wish to create a similar file containing helper functions relevant to your own application and conding style. A great place to include these functions are the “start” files. Within your start/global.php
file, which is included on every request to the application, you may simply require your own helpers.php
file:
Laravel 有一个文件(support/helpers.php
)里面都是辅助函数。你或许希望创建一个类似的文件来存储你自己的辅助函数。“start”文件是个不错的入口,该文件会在应用的每一次请求时被访问。在start/global.php
里,你可以引入你自己写的helpers.php
文件,就像这样:
// Within app/start/global.php
require_once __DIR__.'/../helpers.php';
//译者注: 该helpers.php文件位于app目录下,需要你自己创建。你想放到别的地方也可以。
Since event listeners obviously do not belongs in the routes.php
file, and can begin to clutter the “start” files, we need another location to place this code. A great option is a service provider. As we've learned, service providers are not strictly for registering bindings in the IoC container. They can be used to do all sorts of work. By grouping related event registrations inside of a service provider, the code stays neatly tucked away behind the scenes of your main application code. View composers, which are a type of event, may also be neatly grouped within service providers.
事件监听器当然不该放到routes.php
文件里面,若直接放到“start”目录下的文件里会比较乱,所以我们要找另外的地方来存放。服务提供者是个好地方。我们之前了解到,服务提供者可不仅仅是用来做依赖注入绑定,还可以干其他事儿。可以将事件监听器用服务提供者来管理起来,让代码更整洁,不至于影响到你应用的主要逻辑代码。视图组件其实和事件差不多,也可以类似的放到服务提供者里面。
For example, a service provider that registers events might look something like this:
例如使用服务提供者进行事件注册可以这样:
<?php namespace QuickBill\Providers;
use Illuminate\Support\ServiceProvider;
class BillingEventsProvider extends ServiceProvider{
public function boot()
{
Event::listen('billing.failed', function($bill)
{
// Handle failed billing event...
});
}
}
After creating the provider, we would simply add it our providers
array within the app/config/app.php
configuration file.
创建好服务提供者后,就可以将它加入到app/config/app.php
配置文件的providers
数组里。
Wear The Boot注意启动流程
Remember, in the example above, we are using the
boot
method for a reason. Theregister
method in a service provider is only intended for binding classes into container.记住在上面的例子里面,我们在
boot
方法里进行编写是有原因的。register
方法只能用来进行依赖注入绑定。
If your application has many customer error handlers, they may start to take over your “start” files. Again, like event handlers, these are best moved into a service provider. The service provider might be named something like QuickBillErrorProvider
. Within the boot
method of this provider you may register all of your custom error handlers. Again, keeps boilerplate code out of the main files of your application. An error handler provider would look something like this:
如果你的应用里面有很多自定义的错误处理方法,那你的“启动”文件可能会很臃肿。和刚才的事件监听器一样,错误处理方法也最好放到服务提供者里面。这种服务提供者可以命名为像QuickBillErrorProvider
这种。然后你在boot
方法里想注册多少错误处理方法都可以了。重申一下精神:让呆板的代码离你应用的业务逻辑越远越好。下方展示了这种服务提供者的一种可能的书写方法:
<?php namespace QuickBill\Providers;
use App, Illuminate\Support\ServiceProvider;
class QuickBillErrorProvider extends ServiceProvider {
public function register()
{
//
}
public function boot()
{
App::error(function(BillingFailedException $e)
{
// Handle failed billing exceptions ...
});
}
}
The Small Solution 简便做法
Of course, if you only have one or two simple error handlers, keeping them in the “start” files is a reasonable and quick solution.
当然如果你只有一两条简单的错误处理方法,那么都写在“启动”文件里面也是一种又快又好的简便做法。
In general, classes may be neatly organized using a PSR-0 structure within a directory of your application. Imperative code such as event listeners, error handlers, and other “registeration” type operations may be placed inside of a service provider. With what we have learned so far, you should be able to make an educated decision on where to place a piece of code. But, don't be hesitate to experiment. The beauty of Laravel is that you can make conventions that work best for you. Discover a structure that works best for your applications, and make sure to share your insights with others!
通常只要遵循PSR-0(译者注:或PSR-4)就可以保持类的整洁。命令式的代码比如事件监听器、错误处理器还有其他“注册”性质的操作都可以放在服务提供者里面。对于什么代码要放在什么地方这个问题,结合你目前为止学到的知识,应当可以给出一个有理有据的答案了。但永远不要害怕试验。Laravel最美妙之处就是你可以做出最适合你自己的风格。去探索和发现最适合你自己应用的结构吧,别忘了和他人分享你的见解!
For example, as you probably noticed above, you might create a Providers
namespace for all of your application's custom service providers, creating a directory structure like so:
例如你可能注意到我们上面的例子,你可以创建个Providers
的命名空间来存放你自己写的服务提供者,目录就类似于这样:
// app
// QuickBill
// Billing
// Extensions
//Pagination
-> Environment.php
// Providers
-> EventPusherServiceProvider.php
// Repositories
User.php
Payment.php
Notice that in the example we have a Providers
and an Extensions
namespace. All of your application's service providers could be stored in the Providers
directory in namespace, and the Extensions
namespace is a convenient place to store extensions made to core framework classes.
看上面的例子我们有Providers
和Extensions
两个命名空间(译者注:分别对应两个同名目录)。你自己写的服务提供者可以放到Providers
命名空间下。那个Extensions
命名空间可以用来存放你对框架核心进行扩展的类。