3

Swift Mailer を使用して、かなり大きな数のメール アドレスのリストにメールを送信しています。メッセージは受信者ごとにわずかにカスタマイズされています。一部のプレースホルダーは一意のテキストに置き換えられます。

Swift_Message1 つのインスタンスを複数回再利用する方が効率的 (ガベージ コレクションが少ないなど) だと思いました。私はただsetTo()setBody()次のアドレスに再度送信します。

これは、通常は html だけの 1 つのパーツ ボディでうまく機能します。しかし... 2番目の部分、通常はテキストが必要な場合はできますaddPart()が、次回はループを回ると、別の部分が追加され、次に別の部分などが追加されます...問題は発生しませんsetBody。既存の機体。

既存のパーツを上書きまたは削除する方法はありますか?

ありがとう

4

3 に答える 3

1

Hendrik と Alasdair による回答を拡張するには、Decorator プラグインの使用を検討することをお勧めします。 http://swiftmailer.org/docs/plugins.html#using-the-decorator-plugin

個々のメッセージ部分を操作する代わりに、プラグインは各受信者のメッセージ全体の必要なプレースホルダーを置き換えます。

例えば

$message = \Swift_Message::newInstance();

$replacements = array();
foreach ($users as $user) {
    $replacements[$user['email']] = array(
        '{username}' => $user['username'],
        '{password}' => $user['password']
    );
    $message->addTo($user['email']);
}
$decorator = new \Swift_Plugins_DecoratorPlugin($replacements);
$mailer->registerPlugin($decorator);

$message
    ->setSubject('Important notice for {username}')
    ->setBody(
        "Hello {username}, we have reset your password to {password}\n" .
        "Please log in and change it at your earliest convenience."
    );
$message->addPart('{username} has been reset with the password: {password}', 'text/plain');
//..
$mailer->send($message);

さらに PHP では、オブジェクトは参照によって渡されるため、個々のパーツの本体またはコンテンツ タイプを直接操作できます。

$textPart = \Swift_MimePart::newInstance('Hello World', 'text/plain');
$htmlPart = clone $textPart;
$htmlPart->setContentType('text/html');
$message->setTo('someone@example.com');
$message->attach($htmlPart);
$message->attach($textPart);
//...
$mailer->send($message);

$textPart->setBody('Something Else');
$htmlPart->setBody('Something Else');
$message->setTo('someone.else@example.com');
$mailer->send($message);

を使用して子パーツを削除することもできます

$message->detach($textPart);

パーツを反復処理する detach を使用する代わりに、どのようaddPartに機能するかを調べてattach、単に呼び出しますsetChildren(array_merge($this->getChildren(), array($part)))

addPartそのため、子パーツを定義することで手動で子パーツを設定できます。これにより、 orの呼び出しが置き換えられますattach

$message->setChildren([$htmlPart, $textPart]);

すべての意図と目的のために、別の受信者のためにメッセージの一部を (わずかではありますが) 異なるコンテンツと共に削除する場合、事実上、新しいメッセージを作成しています。プログラミング ロジックは$message = \Swift_Message::newInstance()、メッセージ部分を置き換える必要があるときに呼び出すことで、それを反映できます。

于 2016-07-21T11:34:47.667 に答える
0

$message->getBody()@tetranz @Hendrik が概説しているように$message->setBody($body)、本体部分に使用できます。

addPart()子の同じメソッドを使用して、(言及したマルチパートの) パーツにアクセスできます。つまり、次のようなものです。

$children = $message->getChildren();
foreach($children as &$child) {
    $c_body = $child->getBody();
    //manipulate as you wish
    $child->setBody($c_body);
}
$message->setChildren($children);

これは Swift v5.0.1 で動作します

于 2015-07-06T16:12:57.813 に答える
0

Swift Mailer Docsによると、reallyのようなメソッドはありませgetBody()ん。

プレースホルダーを含む実際のメッセージテンプレートsetBody()を変数に保存し、反復ごとに使用して、メッセージの本文全体を新しい受信者の解析済みテンプレートに置き換えることをお勧めします。

あなたのコードは次のようになると思います:

$template = '<h1>Hello {{firstname}}</h1>, ...';
$recipients = [
    ['firstname' => 'John', 'email' => 'john@example.com'],
    ...
];
$message = Swift_Message::newInstance('Subject here');

foreach ($recipients as $recipient) {
    $body = str_replace('{{firstname}}', $recipient['firstname'], $template);
    $message->setBody($body, 'text/html');

    // continue building the mail object and send it ...
}

このようにして、実際にすべてのメールで Swift_Message インスタンスを再利用できます。インスタンスを再利用したり、ループの繰り返しごとに新しいインスタンスを作成したりしても、PHP に違いはありません。

于 2014-02-08T11:48:06.960 に答える