Php 可以使用“App::make(';\App\User';)”创建实例,但不能使用“new User()”`
这就是模型:Php 可以使用“App::make(';\App\User';)”创建实例,但不能使用“new User()”`,php,laravel,dependency-injection,Php,Laravel,Dependency Injection,这就是模型: namespace App; use L5SimpleFM\FileMakerModels\BaseModel; class User extends BaseModel { protected $connection = 'filemaker'; protected $layoutName = 'Web : User'; } 它扩展了这个抽象类: namespace L5SimpleFM\FileMakerModels; use L5SimpleFM\Con
namespace App;
use L5SimpleFM\FileMakerModels\BaseModel;
class User extends BaseModel
{
protected $connection = 'filemaker';
protected $layoutName = 'Web : User';
}
它扩展了这个抽象类:
namespace L5SimpleFM\FileMakerModels;
use L5SimpleFM\Contracts\FileMakerInterface;
abstract class BaseModel
{
protected $layoutName;
protected $connection;
public function __construct(FileMakerInterface $fm)
{
$this->connection = $fm->setLayout($this->layoutName);
}
...
}
这个抽象类有一个接口的实例(?)。。现在,我不完全理解这种情况下的依赖注入。当我尝试使用newuser
创建我的用户模型的实例时,它失败了,因为它说它需要\uu构造函数中的一个参数,因为它扩展了抽象类BaseModel
但是,我可以使用App::make('\App\User')
创建一个实例,如果我创建一个到该方法的路由,也可以在控制器中创建一个实例并获得结果,如下例所示:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\User;
class UserController extends Controller
{
protected $user;
public function __construct(User $users)
{
$this->user = $users;
}
public function findUsers()
{
$result = $this->user->findAll()->executeCommand();
$records = $result->getRows();
return compact('records');
}
}
路线:
Route::get('user', 'UserController@findUsers');
当访问上述路径时,我会得到所需的输出,但当我在artisan tinker中键入new\App\User
时,我会得到:
TypeError:函数L5SimpleFM\FileMakerModels\BaseModel::\uuu construct(),0的参数太少,在C:\xampp\htdocs\FMTest\vendor\psy\psysh\src\psy\ExecutionLoop\Loop.php(90):eval()的代码位于第1行,预期正好为1
但是$x=App::make('\App\User')
可以工作,我可以在$x
上运行方法
请帮助我理解这一点。编辑
由于OP澄清了BaseClass
是第三方软件包,现在这是正确的答案:
namespace App;
use L5SimpleFM\FileMakerModels\BaseModel;
class User extends BaseModel
{
protected $connection = 'filemaker';
protected $layoutName = 'Web : User';
function __construct () {
parent::__construct(app(FileMakerInterface::class));
}
}
Laravel不在所有位置提供DI(依赖性注射)。文档通常会提示或让您知道在哪里可以请求签名中的依赖项,如控制器方法或构造函数中的依赖项。Laravel的模型构造函数不符合DI请求的条件,因为实例化模型和分配数据是通过ORM插入数据的一种方法
要解决您的问题,请通过全局app()
helper请求FileMakerInterface
,而不是通过构造函数请求
namespace L5SimpleFM\FileMakerModels;
use L5SimpleFM\Contracts\FileMakerInterface;
abstract class BaseModel
{
protected $layoutName;
protected $connection;
public function __construct()
{
$this->connection = app(FileMakerInterface::class)->setLayout($this->layoutName);
}
// ...
}
请参见“但不要使用新用户();
”-您在哪里有新用户()
?在你的UserController
中,你传递的国籍
是你没有的使用的。我没有。我试图在tinker中执行此操作,但它返回了一个错误,表示我需要传递一个参数。尽管在tinker App::make()中可以工作,但请向我们显示错误的正确代码。标题当前与您发布的代码无关。Laravels容器使用反射来检查需要在构造函数中注入哪些类,然后在您使用App::make('\App\User')
时自动为您注入这些类。如果手动创建实例,则需要手动注入依赖项。由于BaseModel
需要实现FileMakerInterface
的类,因此需要传递实现该接口的类的实例。类似于:new User(new SomeClass)
。FileMakerInterface是一个接口,但不是一个类。@Varin如果OP注册了一个实现FileMakerInterface
的提供程序,Laravel将注入该提供程序。好的,它确实是这样工作的!你能再解释一下吗?这不是一种“黑”的方式吗?(请记住,BaseModel是我通过composer需要的包中的一个类,而不是我自己的文件)您不应该修改通过composer安装的包提供的文件。如果您将依赖项安装到其他地方,它们将被删除。您有两种选择:使用new\App\User(App(FileMakerInterface::class));实例化新用户或重写\App\User中的基本模型构造函数时File@Varin如果基类来自供应商,那么@shock\u gone\u wild是正确的,请不要修改基类
。相反,我会覆盖你的\App\User
控件并注入依赖性。