为何使用App::make('\App\User')能创建实例,new User()却无法创建?
问题原因分析
这问题我之前也碰到过,核心差异就在Laravel服务容器的依赖注入能力上。你看你的BaseModel构造函数:
public function __construct(FileMakerInterface $fm) { $this->connection = $fm->setLayout($this->layoutName); }
它要求必须传入一个FileMakerInterface的实现实例才能完成初始化。当你直接用new User()时,PHP会严格按照构造函数的参数要求执行——你没传$fm参数,自然会抛出参数缺失的错误。
而App::make('\App\User')是通过Laravel的服务容器来创建实例的:容器会自动扫描类的构造函数依赖,找到你之前绑定到容器的FileMakerInterface实现类,自动把实例注入进去,所以能成功创建User对象。
解决方案
给你几个不同场景下的解决方案,优先推荐符合Laravel设计理念的方式:
方法1:用Laravel容器解析(最推荐)
继续使用App::make(),或者更简洁的resolve()辅助函数:
$user = resolve(\App\User::class);
如果是在控制器、服务类里,直接通过构造函数注入User实例更优雅,Laravel会自动处理整个依赖链:
class UserController extends Controller { private $userModel; public function __construct(\App\User $userModel) { $this->userModel = $userModel; } public function someMethod() { // 直接使用$this->userModel即可 $users = $this->userModel->someQueryMethod(); } }
方法2:手动传入依赖(应急场景用)
如果一定要用new User()的写法,你可以先从容器中取出FileMakerInterface的实例再传入:
$fmInstance = App::make(\L5SimpleFM\Contracts\FileMakerInterface::class); $user = new \App\User($fmInstance);
不过这种写法违背了Laravel依赖注入的设计初衷,会让代码耦合度变高,不建议在业务代码中大量使用。
方法3:修改BaseModel构造函数(谨慎使用)
如果你的业务场景确实需要无参数实例化,可以给BaseModel的构造函数参数设置默认值,或者添加无参数分支:
namespace L5SimpleFM\FileMakerModels; use L5SimpleFM\Contracts\FileMakerInterface; abstract class BaseModel { protected $layoutName; protected $connection; public function __construct(FileMakerInterface $fm = null) { if ($fm !== null) { $this->connection = $fm->setLayout($this->layoutName); } } ... }
但这种方式需要你后续手动处理connection的初始化逻辑,容易引入潜在的bug,只有在特殊场景下才考虑使用。
内容的提问来源于stack exchange,提问作者Varin
相关产品推荐
相关产品推荐

