Laravel 邮件:传递字符串而不是视图

Posted

技术标签:

【中文标题】Laravel 邮件:传递字符串而不是视图【英文标题】:Laravel mail: pass string instead of view 【发布时间】:2014-11-26 05:00:56 【问题描述】:

我想使用 laravel 发送一封确认邮件。 laravel Mail::send() 函数似乎只接受系统上文件的路径。 问题是我的邮件模板存储在数据库中,而不是系统上的文件中。

如何将纯内容传递到电子邮件?

例子:

$content = "Hi,welcome user!";

Mail::send($content,$data,function());

【问题讨论】:

【参考方案1】:

Mailer 类将一个字符串传递给addContent,它通过各种其他方法调用views->make()。因此,直接传递内容字符串将不起作用,因为它会尝试加载该名称的视图。

您需要做的是创建一个简单地回显$content的视图

// mail-template.php
<?php echo $content; ?>

然后在运行时将您的字符串插入该视图。

$content = "Hi,welcome user!";

$data = [
    'content' => $content
];

Mail::send('mail-template', $data, function()  );

【讨论】:

不是很优雅,我更喜欢 Jarek Tkaczyk 方式:) 这个答案非常具有误导性,不知道为什么 op 接受了这个答案。 Jarek Tkaczyk 和 Sajjad Ashraf 已正确回答【参考方案2】:

更新:在 Laravel 5 中,您可以改用 raw

Mail::raw('Hi, welcome user!', function ($message) 
  $message->to(..)
    ->subject(..);
);

这就是你的做法:

Mail::send([], [], function ($message) 
  $message->to(..)
    ->subject(..)
    // here comes what you want
    ->setBody('Hi, welcome user!'); // assuming text/plain
    // or:
    ->setBody('<h1>Hi, welcome user!</h1>', 'text/html'); // for HTML rich messages
);

【讨论】:

对于 html 电子邮件(需要额外参数),请参阅@sajjad-ashraf 的答案。合并可能好吗? true,在@Sajjad 的回答中添加 这种情况下可以使用onConnection吗? 以及如何在 laravel 5 中设置 text/html?? 不幸的是,如果您想 Mail::queue 消息,他将无法工作,向您抛出 InvalidArgumentException 异常 'Only mailables may be queued.'【参考方案3】:

对于 Html 电子邮件

Mail::send(array(), array(), function ($message) use ($html) 
  $message->to(..)
    ->subject(..)
    ->from(..)
    ->setBody($html, 'text/html');
);

【讨论】:

大概您可以设置多个具有不同内容类型的正文,因此具有text/htmltext/plain 部分的多部分电子邮件? @Jason 函数 (github.com/laravel/framework/blob/master/src/Illuminate/Mail/…) 使用addPart() 作为普通部分而不是setBody(),同时设置了 HTML 部分 你能帮我解决这个问题吗?我有这样的身体,$html = "Hello username",我怎样才能动态传递用户名?【参考方案4】:

这与问题没有直接关系,但对于那些在保留自定义 HTML 版本的同时搜索设置电子邮件的纯文本版本的问题,您可以使用此示例:

Mail::raw([], function($message) 
    $message->from('contact@company.com', 'Company name');
    $message->to('johndoe@gmail.com');
    $message->subject('5% off all our website');
    $message->setBody( '<html><h1>5% off its awesome</h1><p>Go get it now !</p></html>', 'text/html' );
    $message->addPart("5% off its awesome\n\nGo get it now!", 'text/plain');
);

如果你问“为什么不将第一个参数设置为纯文本?”,我做了一个测试,它只需要 html 部分,忽略原始部分。

如果您需要使用附加变量,匿名函数将需要您使用use() 语句,如下所示:

Mail::raw([], function($message) use($html, $plain, $to, $subject, $formEmail, $formName)
    $message->from($fromEmail, $fromName);
    $message->to($to);
    $message->subject($subject);
    $message->setBody($html, 'text/html' ); // dont miss the '<html></html>' or your spam score will increase !
    $message->addPart($plain, 'text/plain');
);

希望对大家有所帮助。

【讨论】:

你是对的,这与问题无关。【参考方案5】:

如果您使用的是可邮寄的。你可以在 build 方法中做这样的事情:

public function build()

 
    return $this->view('email')
        ->with(['html'=>'This is the message']);

您只需在资源文件夹中创建刀片视图email.blade.php

然后在刀片中你可以使用 laravel 刀片语法来引用你的字符串

 <html>
    <body>
      $html
    </body>
  </html>

 <html>
    <body>
      !!$html!!
    </body>
 </html>

如果您的原始文本包含 HTML 标记 我希望这适用于那些将模板存储在数据库中并希望利用 Laravel 中的 Mailables 类的人。

【讨论】:

【参考方案6】:

要使用 Laravel Mailables 发送原始 html、文本等,您可以

在您的 Mailable 中覆盖 Mailable->send() 并在其中使用先前响应中的方法:

send([], [], function($message) $message->setBody()  )

根本不需要在你的构建函数中调用 $this->view()。

【讨论】:

【参考方案7】:

如你所知

只有邮件可以排队。

意思是,如果你使用ShouldQueue接口

1) 首先,你应该一直这样做

php artisan queue:restart

2) 其次,在您的邮件中,您可以使用html 方法(在 laravel 5.8 中测试)

public function build(): self

    return $this
            ->html('
                <html>
                    <body>
                        ForwardEmail
                    </body>
                </html>
            ')
            ->subject(config('app.name') . ' ' . 'email forwarded')
            ->attachData($this->content, 'email.eml', [
                'mime' => 'application/eml',
    ]);

【讨论】:

【参考方案8】:

试试

public function build()

    $message = 'Hi,welcome user!'
    return $this->html($message)->subject($message);

【讨论】:

【参考方案9】:

我有一个类似的问题,我的电子邮件的 HTML 和/或纯文本不是由视图构建的,我不想为它们创建一个虚拟视图(如 @Matthew Odedoyin 所建议的那样)。

正如其他人评论的那样,您可以使用$this-&gt;html() 来设置邮件的 HTML 内容,但是如果您希望您的电子邮件同时具有 HTML 和纯文本内容怎么办?

不幸的是$this-&gt;text() 只取景,但我通过使用解决了这个问题:

$this->text(new HtmlString('Here is the plain text content'));

呈现HTMLString 的内容而不是视图。

【讨论】:

+1。这是唯一对我有用的答案,因为我提前构建了 Mailable,所以我不能使用 send() 方法。令人失望的是,当 HTML 已经可以作为字符串添加时,需要这种解决方法来制作多部分电子邮件。 这正是我所需要的。 Mailtrap 有一个“文本”选项卡,它显示电子邮件的纯文本版本,供任何使用 Mailtrap 进行测试的人使用。 谢谢,有帮助!【参考方案10】:

这可以在 Mailable 实现中完成,使用纯文本和 html 内容部分:

  public function build() 

    // Text and html content sections we wish to use in place of view output
    $bodyHtml = ...
    $bodyText = ...

    // Internally, Mailer::renderView($view) interprets $view as the name of a blade template
    // unless, instead of string, it is set to an object implementing Htmlable,
    // in which case it returns the result $view->toHtml()
    $htmlViewAlternative = new class($bodyHtml) implements Htmlable 
      protected string $html;
      public function __construct($html) 
        $this->html = $html;
      
      public function toHtml(): string 
        return $this->html;
      
    ;

    // We can now set both the html and text content sections without
    // involving blade templates. One minor hitch is the Mailable::view($view)
    // documents $view as being a string, which is incorrect if you follow
    // the convoluted downstream logic. 
    /** @noinspection PhpParamsInspection */
    return $this
      ->to(...)
      ->from(...)
      ->subject(...)
      ->view([
        'html' => $htmlViewAlternative,
        'raw' => $bodyText
      ]);
  

【讨论】:

以上是关于Laravel 邮件:传递字符串而不是视图的主要内容,如果未能解决你的问题,请参考以下文章

Laravel(4.1.24)将查询输出传递给视图时数组到字符串的转换

将参数(当前选择的 $this->user->id 而不是 auth()->user()->id)从视图传递到 livewire + laravel 中的 createShow

Laravel/Vue - 传递数据:Json 嵌套值作为字符串

当参数作为整数传递时,Laravel 返回零而不是实际的单元格值

Laravel 将数据从一个视图传递到另一个视图

Laravel教程 三:视图变量传递和Blade