Проблема с внедрением зависимостей в laravel - PullRequest
1 голос
/ 14 октября 2019

Я только что узнал о служебном контейнере laravel и внедрении зависимостей, чтобы попробовать это, я создал MailgunServiceProvider для создания экземпляра клиента mailgun, у меня есть черта SendMail, которая действует как оболочка для Mailgun:

Однако переменная $ mailgun возвращает ноль, я получаю следующее сообщение:

message Call to a member function messages() on null
exception   Symfony\Component\Debug\Exception\FatalThrowableError
file    C:\xampp\htdocs\dogmedia.com\app\Traits\SendMail.php
line    24

MailgunServiceProvider

<?php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Mailgun\HttpClientConfigurator;
use Mailgun\Mailgun;



class MailgunServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(Mailgun::class, function()
        {
            return Mailgun::create(config('mail.mailgun.secret'), 'https://api.eu.mailgun.net');
        });
    }
}

И моя черта:

<?php
namespace App\Traits;

use Mailgun\Mailgun;


trait SendMail
{

    protected $mailgun;

    public function __construct(Mailgun $mailgun)
    {
        $this->mailgun = $mailgun;
    }


    public function sendMail($view, $mailData, $subject, $to)
    {
        //dd($this->mailgun); this returns null

        $html = view($view, compact('mailData'))->render();

        $result = $this->mailgun->messages()->send(config('mail.mailgun.domain'), [
            'from' => config('mail.from.name').' <'.config('mail.from.address').'>',
            'to' => $to,
            'subject' => $subject,
            'html' => $html,
        ]);

        return $result;
    }


}

Этокласс, использующий мою черту.

<?php
namespace App\Http\Controllers;


use Mailgun\Mailgun;
use Illuminate\Http\Request;
use App\Http\Validators\ContactValidator;
use App\Models\General;
use App\Models\Post;
use App\Traits\SendMail;


class ContactController extends Controller
{
    use SendMail;


    public function __construct(){}


    public function sendContactMail1(Request $request)
    {
        //$validatedData = $request->validate(ContactValidator::$sendContactMail1);

        $mailData = 
        [
            'phone'=> $request->input('phone')
        ];

        $mail = $this->sendMail('emails.contacts.contact-mail-1', $mailData, 'Nuevo contacto en '.config('app.name'), 'gabogabans@gmail.com');

        return response()->json([
            'mail' => $mail,
        ]);
    }


}

1 Ответ

0 голосов
/ 14 октября 2019

Методы, определенные в определении класса, будут иметь приоритет над методами черты. Поэтому, если в вашем классе определен конструктор, метод конструктора черты не будет применен.

"Унаследованный член базового класса переопределяется членом, вставленным в Trait. Порядок приоритета таков:члены из текущего класса переопределяют методы Trait, которые, в свою очередь, переопределяют унаследованные методы. " PHP Manual - Черты - Приоритет

class RandomClass
{
    use SendMail;

    public function __construct()
    {
    }
}

Конструктор, определенный в классе, будет использоваться вместо метода с тем же именем из черты.

Вы можете полностью избежать работы с конструктором, если бы метод sendMail получил экземпляр нужного вам класса Mailgun из контейнера, если вы предпочитаете:

$mailgun = app(\Mailgun\Mailgun::class);
...