自動的に処理を実行させるCRON(クーロン)は、仕事をしていてときどき利用することがあります。それほど頻繁に作るものではありませんが、定期的に何かプログラムを実行したいというときに使います。今回、ちょっと作ってみたいプログラムがあってそれを毎日定時に動かしたいのでCRONを使おうと思います。サーバーはさくらスタンダードなのでそこでCRONを動かす方法について書きます。
CRON(クーロン)とは何?
そもそもCRONとはなんなのかググってみました。
CRONとは、UNIX系システムの常駐プログラム(デーモン)の一種で、ユーザの設定したスケジュールに基づいて指定したコマンドやシェルスクリプトなどを自動実行してくれるプログラム。
大体思っていたことと一致していました。シェルスクリプトだけでなく、コマンドラインからphpも実行できるので今回は慣れているphpで実行させるプログラムを作って動かしてみようと思います。
余談ですが、wikipediaによれば日本ではクーロンと呼ばれることが多いですが、英語圏ではクロンあるいはクローンと呼ばれるようです。あれ?クローン?細胞から生物を複製…?は clone でした。RとLは違ってもほぼスペルが同じなので同じように読むようですね。
わたし的には長いことクーロンと呼んできてしまったのでクーロンでいきたいと思います。
* 机上のクーロン…というギャグが使えなくなりますし…(^_^;
実行させるプログラムをPHPで作ってみる
定期的に実行させるプログラムをPHPで作ってみます。
内容はは曜日によって違うメッセージを送る、というものです。曜日によって違うメッセージはデータ用のファイルに日曜日から1行ずつ土曜日まで入力します。
庭の手入れ 不燃ゴミか有害ゴミ 可燃ゴミ ペットボトル2週に1回 プラスチック びんか缶 可燃ゴミと紙2週に1回 買い出し
こんな感じ。これを適当な名前を付けて保存します。例として、week7369408.xxx という名前で保存したとします。
プログラムは、
<?php /* Name: today-todo 曜日別にメールを送信する */ if (!isset($argv)){ $argv = ''; } $todayTodo = new today_todo($argv); $todayTodo->sendMail(); Class today_todo { public $filename; public $appid = 'C8qci363a5z53NNA'; public $secret = 'YyoeibYedKMNQfxn30MTMxIeq9Hdopd'; public $subject = '【自動送信】今日の予定'; public $week; public $weekDayString = array('日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'); public function __construct($argv) { if($argv == ''){ $requestAppid = $this->_request('appid'); $requestSecret = $this->_request('secret'); } else { if (count($argv) > 1){ $requestAppid = $argv[1]; $requestSecret = $argv[2]; } else { exit('error argv count'); } } if(($this->appid == $requestAppid) AND ($this->secret == $requestSecret)){ $this->filename = 'week7369408.xxx'; } else { exit('error'); } $this->week = date('w'); } public function checkFileExist(){ // その日のファイルがあるかどうかをチェックする if (file_exists($this->filename)) { // ファイルあり return true; } else { // ファイルなし return false; } } protected function _getInInformation(){ $lines = file_get_contents($this->filename); if($lines){ return explode("\n", $lines); } return ''; } public function sendMail(){ if (file_exists($this->filename)) { // ファイルあり $lines = $this->_getInInformation(); } else { // ファイルなし exit('error file not exist'); } if (isset($lines[$this->week])) { // 今日のメッセージ $todayMessage = $lines[$this->week]; } else { exit('week file error'); } // 送り先 $sendTo = 'mika@example.com'; // 送信元 $sendFromMail = 'umoto@example.com'; // header $sendHeaders = "From: umoto@example.com\r\n"; // subject $sendSubject = $this->subject; // bodyy $sendMessage = "■本日(". $this->weekDayString[$this->week]. ")の予定■\n\n". $todayMessage; //送信処理 mb_language('ja'); mb_internal_encoding('UTF-8'); if (mb_send_mail($sendTo, $sendSubject, $sendMessage, $sendHeaders)) { echo 'send mail success'; }else{ echo 'send mail failed'; } } protected function _request($field){ if (isset($_GET[$field])){ return $this->_sanitize($_GET[$field]); } return ''; } protected function _sanitize($arr){ if(is_array($arr)){ foreach($arr as $key => $var){ if(is_array($var)){ $arr[$key] = $this->_sanitize($var); }else{ $arr[$key] = htmlspecialchars($var); } } } else { return htmlspecialchars($arr); } return $arr; } }
こんな感じに書きました。
ブラウザとコマンドラインの両方から実行できるようにしたかったので、appidとsecretの受け取りを両方で行えるようにしています。コマンドラインからの引数は $argv という変数に入るみたいです。
アクセスするだけでメールが送れてしまうのでURLが分かってもappidとsecretが一致しなければなにもしないというようなコードにしてみました。appidとはsecretの名前は、APIから持って来てますがプログラムの中身的には一致すればOKという簡単なコードになってます。
appidとsecretのチェックがOKであれば、曜日別のメッセージをファイルから参照してメールを送信します。
today-todo というフォルダにプログラム today-todo.php とデータファイル week7369408.xxx を入れて、サーバーの www の下にアップロードしておきます。
実際はたぶんそんなに簡単なロジックでないのかと思いますが、今回はCRONを動かしてみたいということだけなのでということでこのままにしておきます。また、ここに書いたappidとsecretの内容は実際のものとは異なっています。
実際にAPIの認証については例えば
などの情報を読んでちゃんと理解しないといけないのですが、今回APIではないのでまた別の機会に勉強したいと思います。
さくらスタンダードのコントロールパネルからCRONの実行を指定する
さくらのコントロールパネルに入ります。
左ブロックの CRONの設定 をクリック。
CRON機能は【上級者向け】です。CRONの設定を誤った場合、思わぬ負荷をサーバに与えることになります。必要がなければ変更しないでください。
と表示されます。心して設定したいと思います。
新規項目の追加 をクリック
入力画面が表示されます。
実行コマンド のところに
cd /home/アカウント/www/today-todo/;/usr/local/bin/php today-todo.php "C8qci363a5z53NNA" "YyoeibYedKMNQfxn30MTMxIeq9Hdopd" 1> /dev/null
と入力します。これは、
cd /home/アカウント/www/today-todo/;
で自分のアカウントのwwwの下のtoday-todoにディレクトリを移動します。
* アカウント には実際のアカウント名を入れます
/usr/local/bin/php today-todo.php "C8qci363a5z53NNA" "YyoeibYedKMNQfxn30MTMxIeq9Hdopd" 1> /dev/null
/usr/local/bin/php today-todo.php と書くことでコマンドラインでphpを実行します。
today-todo.php “C8qci363a5z53NNA” “YyoeibYedKMNQfxn30MTMxIeq9Hdopd” で今回動かしたいプログラムの名前を書き、引数をダブルコーテーションで囲って渡します。ブラウザからからであれば http://example.com/today-todo.php?appid=C8qci363a5z53NNA&secret=YyoeibYedKMNQfxn30MTMxIeq9Hdopd と書くような感じです。
1> /dev/null とついてるのは コマンドの標準出力を postmaster へ送らない ためです。
毎日、朝8時に実行させたいのでこのように指定します。は全部のという意味なので月と日はにします。もし9月だけとかとしたければ月に9と入れれば良いのだと思います。曜日は特に絞ることがないので、チェックはしないでおきます。
ここまで指定したら 送信 をクリックします。
一覧にこのように登録されました。
実際にその時間になったらメールが飛んだかどうか?
実際にその時間になったらメールが飛んだかどうか?…ですが、飛びました(^^)/
こんなメールが届いていました。そう、今日は日曜日だったのでした。
中身は、
こんな感じです。平日は毎日ゴミ出しの情報がやってくるので実際に便利に使えそうです。
まとめ:CRON処理って便利ですね
こんな感じで割と簡単に設置できて毎日忘れずにメールをくれるので、CRON処理って楽しいです。
とはいえ自動的にサーバーで何かをさせる訳なので間違って永久ループして、永久にメールが来ちゃったら(こわい…ガクガクブルブル)なことのなきよう、慎重に慎重を重ねた上で実行しなければと思っています。
また、CRON処理を画面から指定できる、さくらスタンダードは便利だと思いました。
コメント
コメント一覧 (1件)
[…] 自動的に処理を実行させるcronをさくらスタンダードで動かしてみる […]