phpmailer 的 $mail->Body 是否可以收納到一個文件中?

火爆浪子
  • 2.8k
$mail->Body = '';

我發現我要寄信時,我會寫入一整個 html + css 語法,還會添加 php 語言
就像是:

$mail->Body = '
    <html>
    <head>
    '.$phpmailerCssStyle.'
    </head>

    <body>
    <div class="edm-layout">
      <img src="'.$host_url.'images/logo.png">
      <div class="line"></div>
    </div>

    <div class="edm-content">
      <div class="edm-hithere">
        嗨,'.$getUser['name'].' <br>XXX '.$prodTotal.' XXXXX<br>XXXXXX'.formatProductPrice($thisTotal).' XXX
      </div>';

        $row_distinct = mysqli_fetch_array($cako_id_distinct);

        $cako_data = $pdo->query(
          "SELECT XXXXXXX "
        );
        $mail->Body .= '
        <div class="edm-products">
          '.$row_distinct['XXXX'];
          
          //.......
          
          </body>
    </html>

類似那麼長的代碼
我是否可以把它收納到一個文件中,只要簡單引入就可以了?

$mail->Body = 'xxx.php'; or require_once...

有辦法實現嗎?
或其他方式?
至少我在這一頁的代碼不會看到這一長串的代碼.....

回复
阅读 1.9k
4 个回答
✓ 已被采纳

上文中所写的代码极其危险

建议对于这种嵌有HTML的内容 通过使用模板文件进行存储,使用占位符的形式来对内容进行替换

建议方案

  • email.template
<html>
    <head>
        {$phpmailer_css_style}
    </head>

    <body>
    <div class="edm-layout">
      <img src="{$host_url}images/logo.png">
      <div class="line"></div>
    </div>

    <div class="edm-content">
      <div class="edm-hithere">
        嗨,{$user_name} <br>XXX {$prod_total}XXXXX<br>XXXXXX{$this_total} XXX
      </div>
      
        <div class="edm-products">
            {$row_distinct}
        </div>
      </div>
    </div>
  </body>
</html>
  • EmailTemplate.php

<?php
$php_version = version_compare(phpversion(), '7');
/**
 * 必须php 7
 */
if ($php_version === -1) {
    die('Need a high version of php 7.1.*');
}
/**
 * EmailTemplate
 */
class EmailTemplate
{
    /**
     * @param string $template_path 模板路径
     * @param array $args 变量组
     * @return string 渲染后的
     * @throws Exception
     */
    public static function render(string $template_path, array $args): string
    {
        if (!file_exists($template_path)) {
            throw new Exception("Not found template fiel.", 1);

        }
        $template = file_get_contents($template_path);
        $result = preg_replace_callback('!\{\$(\w+)\}!', function ($matches) use ($args) {
            $arg = $matches[1];
            return $args[$arg] ?? '';
        }, $template);
        return $result;
    }
}
  • demo.php
$body = EmailTemplate::render(
    'email.template',
    [
        'host_url' => 'http://xxx',
        'phpmailer_css_style' => 'empty',
        'user_name' => '张三',
        'prod_total' => '100.00',
        'this_total' => '10000.00',
        'row_distinct' => 'empty',
    ]
);

这样就实现了一个简单的模板替换。

  • 答案:可以
  • 解决方案:Smarty框架的fetch方法
  • 案例(就是来自文档):

    • 该方法简单使用:

      
      <?php
      include('Smarty.class.php');
      $smarty = new Smarty;
      
      $smarty->setCaching(true);
      
      // 按照URL来MD5生成一个特定的缓存ID
      $cache_id = md5($_SERVER['REQUEST_URI']);
      
      // 捕获输出
      $output = $smarty->fetch('index.tpl', $cache_id);
      
      // 处理输出的内容
      echo $output;
      ?>
      
          
    • 模板:

      // 这是模板
      Dear {$contact_info.name},
      
      Welcome and thank you for signing up as a member of our user group.
      
      Click on the link below to login with your user name
      of '{$contact_info.username}' so you can post in our forums.
      
      {$login_url}
      
      List master
      
      {textformat wrap=40}
      This is some long-winded disclaimer text that would automatically get wrapped
      at 40 characters. This helps make the text easier to read in mail programs that
      do not wrap sentences for you.
      {/textformat}
      
      
    • 发送邮件:

      
      <?php
      
      // 从数据库或其他来源获取到$contact_info
      
      $smarty->assign('contact_info',$contact_info);
      $smarty->assign('login_url',"http://{$_SERVER['SERVER_NAME']}/login");
      
      mail($contact_info['email'], 'Thank You', $smarty->fetch('email_body.tpl'));
      
      ?>
      
  • 原理及其说明:

    • 框架中的模板引擎本质就是将模板解析到成目标字符串,然后交由HTTP返回客户端
    • 而模板引擎和框架本身是独立存在的,所以模板引擎肯定会有一个方法,作用是:(resultText)=F(template),在Smarty中就是fetch方法
    • 理论上,模板引擎都可以实现你的需求
    • 而且,使用模板引擎比起自己来拼接,不管是维护性、安全性、鲁棒性都更好

举个简单的例子吧。

demo.php

<?php
$getUser = [
    'name' => '张三'
];
$prodTotal = '999';

$body = require('email.php');

echo $body;

email.php

<?php
return '嗨,'.$getUser['name'].' <br>XXX '.$prodTotal.' XXXXX<br>XXXXXX';

运行 demo.php,输出:

嗨,张三 
XXX 999 XXXXX
XXXXXX

谢邀,确实可以写的很简单,但不是这样写:
$mail->Body = 'xxx.php'; or require_once...
你可以这样写

$body = get_file_contents('xxx.html');
$body = str_replace('{{head}}',$head,$body);
$body = str_replace('{{contant}}',$contant,$contant);
$mail->Body = $body;
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏