功能等价性
|
|
// 以下三行代码完全等效 $mailer = app('mailer'); $mailer = $this->app->make('mailer'); $mailer = App::make('mailer'); |
它们都会从 Laravel 服务容器中解析出 'mailer' 绑定的实例。
区别详解
1. app('mailer') - 全局辅助函数
|
|
// 在任何地方都可以使用(全局函数) class OrderService { public function processOrder() { // 在类的任何方法中都可以直接调用 $mailer = app('mailer'); $mailer->send(...); } } function some_helper_function() { // 在辅助函数中也可以使用 $mailer = app('mailer'); } |
特点:
-
全局可用,不需要依赖注入
-
代码简洁
-
适合在无法使用依赖注入的地方
2. $this->app->make('mailer') - 容器实例方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
class CustomServiceProvider extends ServiceProvider { // 在服务提供者中,$this->app 可用 public function register() { $mailer = $this->app->make('mailer'); } } class SomeClass { protected $app; // 需要先获得容器实例 public function __construct(Container $app) { $this->app = $app; } public function someMethod() { $mailer = $this->app->make('mailer'); } } |
特点:
-
需要先获得容器实例 ($this->app)
-
主要在服务提供者中方便使用
-
更面向对象的方式
使用场景对比
在服务提供者中(推荐使用 $this->app)
|
|
class MailServiceProvider extends ServiceProvider { public function register() { // ✅ 在服务提供者中,使用 $this->app 更自然 $this->app->singleton('mailer', function ($app) { return new Mailer($app->make('config')); }); // 解析其他服务来配置当前服务 $config = $this->app->make('config'); $logger = $this->app->make('log'); } } |
在控制器中(推荐使用 app() 或依赖注入)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
class UserController extends Controller { // ✅ 最佳实践:依赖注入 public function welcome(Mailer $mailer) { $mailer->send(...); } // ⚠️ 次选:使用辅助函数 public function backupMethod() { $mailer = app('mailer'); // 简洁 $mailer->send(...); } // ❌ 不推荐:手动解析容器 public function __construct(Container $app) { $this->app = $app; // 不必要的复杂 } public function complexMethod() { $mailer = $this->app->make('mailer'); // 冗长 } } |
在普通类中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
class OrderProcessor { // ✅ 推荐:依赖注入 public function __construct(private Mailer $mailer) {} // ⚠️ 如果无法注入,使用辅助函数 public function process() { $mailer = app('mailer'); // 简单直接 } // ❌ 不推荐:注入整个容器 public function __construct(private Container $app) {} public function process() { $mailer = $this->app->make('mailer'); // 过于复杂 } } |
性能考虑
实际上性能差异可以忽略不计,因为 app() 辅助函数内部就是调用容器:
|
|
// app() 辅助函数的简化实现 function app($abstract = null, array $parameters = []) { if (is_null($abstract)) { return Container::getInstance(); } return Container::getInstance()->make($abstract, $parameters); } |
代码风格建议
遵循 Laravel 约定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
// 在服务提供者中 class SomeServiceProvider extends ServiceProvider { public function register() { // ✅ 符合 Laravel 风格 $this->app->bind(...); $instance = $this->app->make(...); } } // 在控制器、作业、监听器等中 class SomeController extends Controller { // ✅ 优先使用依赖注入 public function method(Mailer $mailer) {} // ✅ 其次使用辅助函数 public function otherMethod() { $mailer = app('mailer'); } } |
现代 Laravel 代码风格
|
|
// 使用 PHP 8 构造函数属性推广 class OrderService { public function __construct( private Mailer $mailer, private PaymentGateway $payment ) {} public function process() { // 直接使用注入的依赖,最简洁 $this->mailer->send(...); $this->payment->charge(...); } } |
总结
最佳实践建议:
-
优先使用依赖注入
-
在无法注入的地方使用 app() 辅助函数
-
在服务提供者中使用 $this->app
-
避免注入整个容器来手动解析
「三年博客,如果觉得我的文章对您有用,请帮助本站成长」
共有 0 - laravel 分析三种语法糖