问题描述
我有一个User雄心勃勃的模型,该模型在其构造函数中采用了UserMailer类的实例,但出现此错误
I have a User eloquent model that takes in an instance of the UserMailer class in its constructor but I get this error
Argument 1 passed to User::__construct() must be an instance of TrainerCompare\Mailers\UserMailer, none given, called in /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 631 and defined
我理解该错误,但无法弄清楚我做错了什么,但是我不太了解命名空间和composer类映射与psr0自动加载的关系.我记得使用composer dump-autoload,不是那样的
I understand the error but can't figure out what I have done wrong but I don't udnerstanding namespacing and composer class map vs psr0 autoloading very well. I have remembered to use composer dump-autoload so it is not that
相关文件夹结构
composer.json
app/
models/
User.php
TrainerCompare/
Mailers/
Mailer.php
UserMailer.php
Services/
Validation/
composer.json自动加载部分. psr-0部分是从我添加验证服务开始的,您可以在TrainerCompare/中看到这些部分,这些类工作得很好.我按照本教程将app/TrainerCompare/Mailers添加到类映射中,以加载mailer类
composer.json autoload section. psr-0 section is there from when I added the validation service you can see in TrainerCompare/ and these classes work great. I added app/TrainerCompare/Mailers to the classmap per the tutorial I am following to get the mailer classes loaded
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/tests/helpers",
"app/TrainerCompare/Mailers"
],
"psr-0":{
"TrainerCompare": "app/"
}
}
User.php
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
use TrainerCompare\Mailers\UserMailer as Mailer;
class User extends BaseModel implements UserInterface, RemindableInterface
{
protected $mailer;
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
}
Mailer.php
Mailer.php
<?php namespace TrainerCompare\Mailers;
use Mail;
/**
* Email mailing class
*/
abstract class Mailer
{
public function __construct()
{
# code...
}
public function sendTo($user, $subject, $view, $data = [])
{
Maill::send($view, $data, function ($message) use ($user, $subject) {
$message->to($user->email)
->subject($subject);
});
}
}
UserMailer.php
UserMailer.php
<?php namespace TrainerCompare\Mailers;
use User;
/**
* User Mailer Class
*/
class UserMailer extends Mailer
{
public function __construct()
{
# code...
}
public function welcome($user)
{
$view = 'emails.users.welcome';
$data = [];
$subject = 'Welcome to Laracsts';
return $this->sendTo($user, $subject, $view, $data);
}
}
推荐答案
口才(re)通过调用在内部创建自己:
Eloquent (re)creates itself internally by calling:
new static
一个示例是创建一个新查询:
An example is in creating a new query:
return with(new static)->newQuery();
我不确定在这种情况下是否可以使用自动依赖关系解析,它应该始终在laravel中运行,但是由于它也具有自己的构造函数方法,因此您至少必须转发对其的调用并支持$attribute
参数:
I'm not sure if automatic dependency resolution would work in this case, it should always work inside laravel, but as it also has it's own constructor method, you must at least forward a call to it and support the $attribute
parameter:
public function __construct(array $attributes = array(), Mailer $mailer)
{
$this->mailer = $mailer;
parent::__construct($attributes);
}
编辑
打开了一个问题来理解它: https://github.com/laravel/framework/issues /3862
Opened an issue to understand it: https://github.com/laravel/framework/issues/3862
编辑2
正如我在评论中所说,您最好创建一个服务,正如您自己指出的那样,这是一个更好的应用程序设计.您不应该使用模型来发送电子邮件.接收用户模型(或只是名称和电子邮件)并将消息发送给该用户的服务将是更好的选择.
As I've said in comment, you better create a service, as pointed by yourself, is a better application design. You should not be using your model to send e-mails. A service that receives a user model (or just name and e-mail) and send the message to that user would be a better way to go.
泰勒·奥特威尔(Taylor Otwell)在本期中对此的回答:
Answer given by Taylor Otwell about it in the issue:
这篇关于无法将类实例传递给构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!