勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

PHPでメルマガを配信する方法(1件ずつ送信するパターン)

   2024/02/25  PHP

以前にPHPでメルマガを配信する方法を書いたけど、BCCだと相手の名前などユーザー情報を記述するわけにはいかず、また、BCCの件数に制限があるみたく、数千件以上配信する場合は小分けにする必要がありそう。なので1件ずつ処理する方法を考えた。

 

ソースコード

mail.php

<?php
//メール本文、件名、配信対象者の検索条件をフォーム等から受け取る。
$body = $_POST['body'];
$subject = $_POST['subject'];
$search = $_POST['search'];

//メールマガジン用のテーブルにflg(今回は配信中が0、配信終了が1と想定)、本文、件名、配信対象者の検索条件を挿入
$sql = '
    INSERT INTO mail_magazine 
        (flg, body, subject, search) 
    VALUES 
        (0, "'.$body.'", "'.$subject.'", "'.$search.'")
';
$row = $mysqli->query($sql);

if( !$row ){
    //エラー処理
}

//send.phpに先ほどメールマガジン用テーブルに入れたIDを渡してバックグラウンドで実行させる。
exec("nohup /usr/bin/php /var/www/html/send.php ".$mysqli->insert_id." > /dev/null &");

send.php

<?php
//送信するメールマガジンの情報を呼び出す。
$sql = '
    SELECT *
    FROM mail_magazine 
    WHERE id = '.$argv[1].' 
';
$row = $mysqli->query($sql);
if( !$row ){
    //エラー処理
}
while($rs = mysql_fetch_array($row)){
    $body = $rs['body'];
    $sucject = $rs['subject'];
    $search = $rs['search'];
}


//配信対象者の情報を呼び出す。
$sql = '
    SELECT *
    FROM user 
    WHERE search = "'.$search.'" 
';
$row = $mysqli->query($sql);
if( !$row ){
    //エラー処理
}


//メールのヘッダー情報設定
$header = 'From: info@hoge.com\n';


//送信処理
while( $rs = $row->fetch_array(MYSQLI_ASSOC) ){
    mb_send_mail($rs['mailaddress'], $subject, $body, $header);
    sleep(1); //1秒ずつ遅延させる
}


//送信が完了すればメールマガジン用のテーブルのフラグを書き換える
$sql = '
    UPDATE mail_magazine 
    SET flg = 1
    WHERE id = '.$argv[1].' 
    LIMIT 1
';
$row = $mysqli->query($sql);
if( !$row ){
    //エラー処理
}

 

使い方

メール本文やタイトルを入力するフォームを作って、その受け取り先をmail.phpにする。mail.phpからsend.phpをバックグラウンド処理させる。

尚、フォームの時点で現在配信中のフラグが立っていないかチェックし、もしも配信中のフラグがあれば「現在配信中のためお待ち下さい」的な表示にし、フォームは非表示にするのが良さそう。

 

バックグラウンド処理

普通にPHPで処理しようとするとブラウザを開きっぱなしにしないといけないけど、これだと途中で閉じたりとかページ更新された場合にどうなるのか分からず怖い。

なので、バックグラウンドで処理できないかと調べたらexec関数でいけるらしい。mail.phpにも書いているけど以下の形で使う。

exec("/usr/bin/php 実行させるPHPファイル名指定 引数1 引数2 > /dev/null &");

最初は引数をsend.php?hoge=1&name=aaaみたいに書いたけど、そうではなく半角スペースで区切って記述する。

受け取り側は$argvという変数で受け取る。$_GET[]では受け取れないので注意。また、$argv[0]はスクリプト名になるので$argv[1]以降を使う。

 

リファレンス

$argv

http://php.net/manual/ja/reserved.variables.argv.php

exec

http://php.net/manual/ja/function.exec.php

 

その他

バックグラウンド処理ってのは初めてだったので勉強になった。まだ実装は出来ていないけど概ね今回の構想でいけそう。

 - PHP

  関連記事

Opauthで「Please change the…」エラーの対応方法

Opauthを使用中に「Notice: Please change the va ...

PHPのHTTPクライアント用ライブラリ「Guzzle」の利用方法

以前に「Requests for PHP」を試したが、似たようなライブラリで「G ...

mysqldumpが使えないレンタルサーバでMySQLのバックアップ

mysqldumpが使えないレンタルサーバで開発を行うことがあり、尚且つ他社に使 ...

PHPでjpg / png画像をAVIF形式の画像に変換する方法

PHPでjpg / png画像をAVIF形式の画像に変換しサーバに保存したい。W ...

PHPでランダムなカラーコードを生成する「RandomColor.php」ライブラリの利用方法

PHPでランダムなカラーコードを生成したい。自作するとなると「0~9」「a~f」 ...