【PHP&Cron】自動でページの更新・変更をメールで受け取る

RSSフィードの送信がなくとも、HTMLに変更があったら自動でメールが届くコードを作りました。

ブログで古い情報を載せたままにするのが嫌なので、定期的に公式サイトの情報を確認できるようにするためです。

いちいちサイトを確認しないでも、ページの更新があった時だけ自動で通知されれば便利だと思います。

フォルダ構成は以下のような感じ。site-check.phpの処理が実行されると、sourceフォルダにテキストファイルが生成されます。

PHPコード

<?php

$check_site_array = array(
  'hoge' => '監視したページのURL', // hoge.txtというテキストが自動で書き出される
  'fuga' => '監視したページのURL'  // fuga.txtというテキストが自動で書き出される
);

// 更新通知先メールアドレス
$mail_address = 'メールアドレス';

$errorlog = '';

// 403エラー対策でHTTPヘッダーを設定
$context = stream_context_create(array(
'http' => array(
  'method' => 'GET',
  'header' => 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
  'timeout' => 10
)));

// システム文字コードを PHPに設定
mb_language( 'ja' );
mb_internal_encoding( 'UTF-8' );

foreach( $check_site_array as $name => $url ) {
  $http_response_header = array();
  $source = @file_get_contents( $url, false, $context );
  if( !$source ) {
    // mb_send_mail($mail_address, "更新通知", "$url サイトURLが変更になった可能性があります。" );
    //エラー処理
    if(count($http_response_header) > 0){
        //「$http_response_header[0]」にはステータスコードがセットされているのでそれを取得
        $status_code = explode(' ', $http_response_header[0]);  //「$status_code[1]」にステータスコードの数字のみが入る
 
        //エラーの判別
        switch($status_code[1]){
            //403エラーの場合
            case 403:
                $errorlog .= "アクセスが拒否されました: " . $url . "\n\n";
                break;
            //404エラーの場合
            case 404:
                $errorlog .= "指定したページが見つかりませんでした: " . $url . "\n\n";
                break;
 
            //500エラーの場合
            case 500:
                $errorlog .= "指定したページがあるサーバーにエラーがあります: " . $url . "\n\n";
                break;
 
            //その他のエラーの場合
            default:
                $errorlog .= "ステータスコード[" . $status_code[1] . "] " . "何らかのエラーによって指定したページのデータを取得できませんでした: " . $url . "\n\n";
                echo $source;
        }
    }else{
        //タイムアウトの場合 or 存在しないドメインだった場合
        $errorlog .= "タイムアウト もしくは URLが間違っています: " . $url . "\n\n";
    }
    continue;
  }
  $text_path = 'source/' .$name . '.txt';

  if( !$current_text = @file_get_contents( $text_path ) ) {
    //テキストファイルがなかったら作成
    file_put_contents( $text_path, $source );
  } elseif( $current_text !== $source ) {
    // 前の文字列と異なる場合、メールを送信
    mb_send_mail($mail_address, "更新通知", "$url が更新されたよ。" );
    // 送信後テキストを上書き
    file_put_contents( $text_path, $source );
  } else {
    // 変更がない場合、そのままスルー
  }
}
// エラーがあった場合、ログを吐き出す
if( $errorlog !== '' ) {
  file_put_contents( 'errorlog.txt', $errorlog );
  mb_send_mail($mail_address, "エラー報告", "エラーが発生しました。ログを確認して下さい。\n\n" . $errorlog );
} elseif( file_exists('errorlog.txt') ) {
  // エラーがなかったらファイルを削除
  unlink( 'errorlog.txt' );
}

追記:エラーログを保存・送信するようにしました。403エラー対策もしました。

$check_site_arrayと$mail_addressはご自身で書き換えて下さい。

ローカルで試そうとしましたが、XAMPPの設定が面倒でした…。

指定されたページのURLのHTMLソースをテキストで保存、次にプログラムが実行された時にHTMLの中身が異なればメールが来る仕組みです。

Cronの登録

Cronというのは、「一日一回」とか「週に一回」など指定の頻度でコマンドを実行してくれる仕組みです。

これを使って、定期的にsite-check.phpを実行してくれるように設定します。

エックスサーバーやConoha Wing、mixhost、さくらインターネットなどの主要レンタルサーバーでは利用できます。

今はConoha Wingを使っていますが、記事作成時はmixhostを使っていたのでmixhostの管理画面で説明します。

共通設定の所で実行頻度を設定できます。

私は1週間に1回に設定しました。そんなガンガンメール来ても困りますし。

テストの段階では5分に1回とかでやってみると良いでしょう。

「コマンド」の所に、以下のコードを挿入します(IDの部分は書き換えて下さい。)

/usr/bin/php /home/mixhostのID/public_html/site-checker/site-check.php

他のレンタルサーバーも似たような設定です。

エックスサーバーは以下を参考にしてください。

https://www.xserver.ne.jp/manual/man_program_cron.php

これで公式サイトのチェックが楽になりました。

あんまりサイトを設定しすぎると、メールがいっぱい来てうざいかもしれません。

運用してみて

HTMLが変わっている場合通知が行くので、バックエンドで動的にHTMLを生成している場合は使えません。毎回通知が来てしまいます。

あと、制限をかけられてfile_get_contentsできないサイトもあるみたいです。

ですので、全てのサイトで利用できるわけではありません。最初は数分おきとかでテストしてみて、問題ないURLだけ残すという感じですね。