3

私は単純な Email() クラスを持っています。私のウェブサイトからメールを送信するために使用されます。

<?
Email::send($to, $subj, $msg, $options);
?>

また、いくつかの PHP 変数を突き刺したプレーンな HTML で記述されたメール テンプレートも多数用意しています。例/inc/email/templates/account_created.php:

<p>Dear <?=$name?>,</p>
<p>Thank you for creating an account at <?=$SITE_NAME?>. To login use the link below:</p>
<p><a href="https://<?=$SITE_URL?>/account" target="_blank"><?=$SITE_NAME?>/account</a></p>

PHP 変数をレンダリングするにはinclude、テンプレートを関数に組み込む必要がありました。しかしinclude、コンテンツを返さず、出力に直接送信するだけなので、バッファ関数でラップする必要がありました。

<?
abstract class Email {
    public static function send($to, $subj, $msg, $options = array()) {
        /* ... */
        ob_start();
        include '/inc/email/templates/account_created.php';
        $msg = ob_get_clean();
        /* ... */
    }
}

その後、関数スコープ内にあるため、PHP 変数がレンダリングされないことに気付きました。そのため、テンプレート内の変数をグローバル化する必要がありました。

<?
global $SITE_NAME, $SITE_URL, $name;
?>
<p>Dear <?=$name?>,</p>
...

問題は、これに対するよりエレガントな解決策があるかどうかです。ob_start()主に、 と を使用した回避策が心配ですglobal。どういうわけか、私には奇妙に思えます。それとも、これはかなり一般的な方法ですか?

4

3 に答える 3

3

これを行う方法の 1 つは、ファイルの内容を変数に読み取ってから、正規表現を使用してプレースホルダーを置き換えることです。たとえば、new-users-template.phtml があります。あなたはそれを読んでいます$content = file_get_content('new-users-templae.phtml');。これらのテンプレートには、、、など%%username%%のプレースホルダーが%%sitename%%あり%%siteurl%%ます。このコンテンツを で処理しstr_replace、プレースホルダーを置き換える必要があります。このコードを何らかの"prepareEmailTemplate"関数に移動し、この関数の結果を関数に入れます"send"

于 2012-12-07T16:44:54.563 に答える
3

この回答で、問題に対するより洗練された解決策を見つけることができます。テンプレート変数をインスタンス化するため
に PHP抽出関数を使用していることに注目してください。
つまり、テンプレートの解析ロジックを電子メール送信機能の外に移動する必要があります。
例えば:

<?php

class SimpleTemplate {
    private $_tpl  = "";
    private $_vars = array();

    function __construct($tpl_name) {
         $this->_tpl = $tpl_name;
    }

    public function __set($name, $value) {
        $this->_vars[$name] = $value;
    }

    public function setVars($values) {
        $this->_vars = $values;
    }

    public function parse() {
        ob_start();
        extract($this->_vars);
        include $this->_tpl;
        return ob_get_clean();
    }
}

abstract class Email {
    public static function send($to, $subj, $msg, $options = array()) {
        /* ... */
    }
}

$tpl = new SimpleTemplate('/inc/email/templates/account_created.php');
$tpl->name = 'Stack Overflow';
$tpl->SITE_NAME = 'site_name';
$tpl->SITE_URL = 'localhost';
Email::send("me@localhost", "Subject", $tpl->parse());

?>
于 2012-12-26T17:49:46.573 に答える
0

1 つの解決策は、必要な変数をテンプレート内ではなく関数内でグローバル化することですsend

public static function send($to, $subj, $msg, $options = array()) {
    global $SITE_NAME, $SITE_URL, $name;

    /* ... */
    ob_start();
    include '/inc/email/templates/account_created.php';
    $msg = ob_get_clean();
    /* ... */
}

別の解決策は、これらの追加の変数をパラメーターとして渡すことです。setテンプレートで必要なパラメーターの数に応じて、関数内のパラメーターの数が大幅に増加する可能性があるため、これは見苦しいかもしれません。この問題を解決するために、このソリューションを実装する別の方法は、これらの余分な変数をハッシュとして渡し、それらの変数をオンザフライで作成することです (関数を使用eval)。次に例を示します。

public static function send($to, $extra_vars = array()) {
    foreach ($extra_vars as $key => $value) {
        eval("\$$key = '$value';");
    }

    /* ... */
    ob_start();
    include '/inc/email/templates/account_created.php';
    $msg = ob_get_clean();
    /* ... */
}

次に、次のように send を呼び出す必要がある場合:

$SITE_NAME = "www.somewebsite.com";
Email::send("recipient", array('SITE_NAME' => $SITE_NAME));
于 2012-12-22T00:31:09.027 に答える