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

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

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

例子:

$content = "Hi,welcome user!";

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

【问题讨论】:

    标签: php email laravel laravel-4 swiftmailer


    【解决方案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
                  ]);
              }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-10-24
              • 2018-07-30
              • 1970-01-01
              • 2020-08-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多