前回、Linux の cron を使ってスケジュール実行をしました。
crontab コマンド(Linuxコマンド)を使ってジョブをスケジュール実行
今回は実際に PHP のプログラムと絡めて、通知メールを作成したいと思います。
やりたいこと
訪問した会社から3ヵ月経過している会社をメールで知らせてくれるSFAのような機能を作りたいと思います。
送信先のメールは users テーブルに登録されているメールアドレスを対象とします。
前提条件
cron はすでにインストールされているとします。
Dockerをお使いの場合は以下のように Dockerfile に cron をインストールしておきましょう。
:
# ミドルウェアのインストール
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim \
libpng-dev \
libpq-dev \
cron \
&& docker-php-ext-install pdo_mysql
:
手順
1)DBのテーブル作成
「会社テーブル(companies)」を以下のように作成します。
訪問した時間(visited_time)はあとで計算して通知メールを飛ばします。
「ユーザテーブル(users)」は以下のように作成します。
Laravel の認証機能(auth)を作るときに作られるテーブルで OK です。
2)ルーティング
ルーティングは以下のように設定します。
Route::get('mail_demo1','MailController@demo1');
crul で http://localhost/mail_demo1 を叩くと通知メールが実行される仕組みになります。
curl とは主に UNIX 系 OS でよく利用されるコマンドおよびプログラムの一つ。様々なプロトコル(FTP、HTTP、HTTPS)を用いて URL で示されるネットワーク上の場所との間でデータの送受信を行うもの。
3)コントローラの作成
MailController の demo1 メソッドを以下のように記述していきます。
class MailController extends Controller
{
public function demo1()
{
/*-------------------------------------
* メール送信先の取得
------------------------------------*/
//結果データの取得
$users = \DB::table('users')->get();
//複数の宛先
foreach($users as $user){
$emails[] = $user->email;
}
/*-------------------------------------
* 訪問期間があいている会社名の取得
------------------------------------*/
//結果データの取得
$companies = \DB::table('companies')->get();
$company_names = []; // 宣言
foreach($companies as $company){
$time1 = strtotime($company->visited_time);
$time2 = time();
$diff_time = ($time2-$time1) / (60 * 60 * 24);
//訪問日から180日以上の会社名を取得
if($diff_time >= 180){
$company_names[]=$company->place_name;
}
}
/*-------------------------------------
* メール送信処理
------------------------------------*/
if(!empty($company_names)){ //会社名が空でない場合のみメール送信
foreach($emails as $email) {
//メール送信(テキスト)
\Mail::send(array('text' => 'email.message_demo1'), ["company_names" => $company_names], function($message) use ($email){
$message->from('us@example.com');
$message->to($email)->subject('メール送信デモ');
});
}
}
return view('mail_demo');
}
}
ビューである mail_demo.blade.php は「テスト通知メール完了」とだけ記述すればいいでしょう。
4)メール本文の作成
Mail ファサードの send() メソッドに入れているメール本文、 message_demo1.blade.php を以下のように記述します。
これはデモのメールです。
訪問してから3カ月以上経過している会社は以下になります。
<?php
foreach($company_names as $company_name){
echo $company_name."\n";
}
?>
5)メール送信(ログに出力)
今回は実際にメール送信するのではなく、Laravelのログファイルに出力されるようにします。
envファイルにある MAIL_DRIVER に log と記述してあげます。
# .env
MAIL_DRIVER = log
:
詳しくは以下のページをご参照ください。
6)cron(スケジューラー)の設定
以下のコマンドを打って、cronを設定します。
$ crontab -e
viエディタが開くので以下のように記述します。
# 5分ごとに http://localhost/mail_demo1 にアクセス
*/5 * * * * curl --request GET 'http://localhost/mail_demo1'
HTTPアクセスをしてコンテンツを取得できるコマンド。wgetコマンドでも同じようなことができる。
# URL をパラメータにしてそのコンテンツを標準出力させるのが、基本的な使い方
$ curl http://www.example.com/
実演
7)動作確認
ログは storage/logs/laravel.log に書き込まれます。
ログローテーションにしたい場合は confi/app.php の設定を変更してやります。
Laravelでのデバッグのやり方について(Logファサード編)
5分後にメールが書き込まれるか確認してみましょう。
以下のように書き込まれていれば OK です。
訪問日から3ヵ月以上経過している会社名だけメール本文に表示されればOKです。
以上です。
仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら。