Web サイトの更新チェックを行うツールが欲しかったので、PHP で作成してみました。一言で言うと、アンテナのようなものです。個人用として使いやすいように作成しています。それなりにできてきましたので、公開します。もし、何か問題になるようでしたら、このページは削除するかもしれません。
何か問題などがありましたら、メールで指摘をお願いします。
wwwcheck.php 目次
wwwcheck-0.5.tar.bz2 (2007.02.18)
バージョン 0.43 からの変更点については、更新履歴を参照してください。
wwwcheck-0.43.tar.bz2 (2006.05.07)
バージョン 0.42 からの変更点については、更新履歴を参照してください。
wwwcheck_0.42_0.43.patch (0.42 から 0.43 への Patch)
wwwcheck-0.42.tar.bz2 (2005.11.25)
バージョン 0.41 からの変更点については、更新履歴を参照してください。
wwwcheck_0.41_0.42.patch (0.41 から 0.42 への Patch)
wwwcheck_0.4_0.41.patch (0.4 から 0.41 への Patch)
バージョン 0.41 以前はセキュリティ問題がありますので、過去のバージョンは削除しました。
古いバージョンからバージョンアップする場合は、バージョンアップについてを参照してください。
バージョン 0.3 で Cross-Site Request Forgery(CSRF) 問題への対処を行いました。0.3 未満のバージョンではセキュリティ問題があると考えていますので、古いバージョンは削除しました。
PHP 4.3.10 RC1 から PHP 4.3.10 と バージョン 0.3 未満の組み合わせで、HTML のフィルタ機能を使用している場合、「全てに適用」というフィルタが消えてしまうという問題があります。バージョン 0.3 ではこの問題への対処も行っています。
レンタルサーバなどでは、CLI版 PHP の実行や外部へのアクセス、ディスク容量など、多くの制限があるため、おそらく動作しません。個人が所有していて、正しく管理されているサーバなどにインストールして使用してください。
詳しく確認した訳ではありませんが、バージョン 0.2 において、Windows 2000 で Apache 1.3.31 と PHP 4.3.9 の組み合わせで動作することは確認しました。ただし、拡張モジュールなどの関係で、不具合や制限があるかもしれません。また、ファイルのロックに flock() を使用していますので、インストール場所のファイルシステムは NTFS を使用する必要があります。
Cygwin で、PHP をコンパイルして使用した場合も、動作するようです。Cygwin で PHP をコンパイルする方法については、Cygwin で Apache 1.3.29 と PHP 4.3.4 の mod_php4 をコンパイルするというメモがありますので、そちらを参照してください。
このスクリプトでは内部の文字コードに UTF-8 を使用しています。スクリプト中で、内部エンコーディングを UTF-8 に切り替えるようにしていますが、php.ini の設定で、mbstring.encoding_translation = On
とmbstring.http_input
の組み合わせによっては、文字コードが正しく変換されず、文字化けする可能性があります。
差分を取得するため、チェック対象になっている HTML 全体を保存しています。多くのサイトを登録すると、それだけディスク容量を消費しますので気をつけてください。
このツールを使用するために、必要な環境、ツールなどです。必須なのは、Web サーバ、PHP の実行環境、mbstring
モジュールです。
Web サーバ(httpd)として、Apache を想定していますが、他の Web サーバでも動作するかもしれません。
PHP のバージョンは、PHP 4.3.0 以上で動作確認をしています。また、PHP 5.0.1 以降でも動作するようです。PHP は、最近のバージョンでも、セキュリティ問題や多くのバグ修正が行われていますので、できる限り最新版の PHP を使用してください。
Web ページの取得の際に使用します。
PHP 4.3.0 以上でソースからコンパイルした場合、configure
オプションに --disable-cli
を指定していなければ、/usr/local/bin/php にインストールされています。Linux ディストリビューションで提供されているパッケージを使用した場合は、/usr/bin/php などにあります。CGI版 PHP でも動作します。
ページの差分取得の際に使用します。設定ページで diff
コマンドのパスを設定すると使用します。
diff
コマンドが設定されていない場合、PHP 拡張モジュール(PECL)の xdiff.so がインストールされていれば、そちらを使用します。
diff
コマンドも xdiff.so もない場合は、PHP で作成した差分取得ライブラリが使用されますが、遅い上に非常に多くのメモリが必要になります。また、memory_limit
によるメモリの制限が設定されている場合、正しく差分を取得できませんので、可能であれば、diff
コマンドか xdiff.so のどちらかを使用してください。
また、ライブラリの中に含まれている diff.inc.php は pukiwiki 1.4.3 に含まれていた diff.php を高速化のため、一つの関数に書き換えて作成したものです。ほとんど、元の形とは違うものになっていますが、アルゴリズムは同一のものです。
Linux や *BSD などの Unix 系の OS では既に存在すると思います。多くの場合、/usr/bin/diff にインストールされています。
Windows の場合、GNU utilities for Win32 などのページで、diff.exe
が含まれたコマンド集の配布を行っていますので、その中から取得するなどしてください。
設定ページで以下のようにコマンドが存在するパスを指定してください。
/usr/bin/diff
C:\php\diff.exe
xdiff.so を作成するためには、libxdiff をインストールする必要があります。libxdiff のインストール後、pear
コマンドでインストールする事ができます。
$ pear install xdiff
PHP の拡張モジュールとして、以下を使用します。mbstring
以外は有効になっていない場合でも動作はしますが、制限事項があります。
mbstring
(必須です)
文字コード変換や、マルチバイト文字列の処理に使用します。有効になっていないと、文字コードの変換が行えず、文字化けを起こした状態になります。
zlib
gzip 圧縮されたファイルを扱うことができるようになります。有効になっていない場合でも動作はしますが、一部の圧縮転送を行えるサーバとの間で、Web ページの取得が速くなります。
openssl
https 接続を行う際に使用します。Proxy を使用した https は行えません。https 接続を行わない場合は必要ありません。
curl
Proxy を使用した https 接続を行う際に使用します。https 接続を行わない場合は必要ありません。
pcntl
CLI 版の PHP から Web ページを取得する際に、効率が良くなります。有効になっていない場合でも動作に問題はありません。
sqlite
データの保存に PECL の SQLite 拡張モジュールを使用できます。通常、データの管理はファイルで行いますが、項目数が増えてくると、SQLite で管理した方が速くなります。
2005.02.20 の時点で個人的に使用している環境は、以下の通りです。
OS : Gentoo Linux Apache : 1.3.33 PHP : 4.3.10 (DSO + CLI)
PHP の configure オプション
./configure \ --with-apxs=/usr/local/apache/bin/apxs \ --enable-mbstring \ --enable-memory-limit \ --enable-pcntl \ --with-curl \ --with-openssl \ --with-zlib \ --without-mysql
wwwcheck-<version>.tar.bz2 を Web 上からアクセスできる場所に展開してください。
$ tar jxvfp wwwcheck-<version>.tar.bz2
必要であれば、ディレクトリ名からバージョン番号を削除します。
$ mv wwwcheck-<version> wwwcheck
次に、wwwcheck を展開したディレクトリに data ディレクトリがありますので、Web サーバの動作権限で書き込み可能なように、権限を与えてください(Web サーバ側でファイルに読み込み、書込みの権限があれば、データディレクトリは 707 である必要はありません。適切な所有者、権限を設定してください)。
$ cd wwwcheck $ chmod 707 data
後は、http://www.example.com/wwwcheck/ など、インストールした場所にブラウザでアクセスして設定を行えば、動作します。最低限の設定というものはありませんが、外部に公開する場合は、ユーザとパスワードの設定は行ってください。また、diff
コマンドのパスが分かっている場合は、できれば設定してください。
「アイテムの追加」で目的の Web ページの URI を入力すると、更新チェック対象に追加されます。しばらくした後、更新チェックボタンを押すとチェック対象の URI を取得し、変更があれば表示します。ログインするなどして、管理権限がある場合、項目の詳細設定や更新後、未訪問のページをフィルタリングする機能などが使用できます。
細かい設定についての解説です。無視しても問題ありません。
ディレクトリ構成は以下のようになっています。
wwwcheck index.php <-- メインスクリプト init.inc.php <-- 設定、初期化スクリプト check.php <-- 更新チェック実行スクリプト(update.php から呼び出されます。) update.php <-- 更新チェック実行スクリプト data <-- 設定、ログデータ保存ディレクトリ lib <-- 各種ライブラリ misc <-- デバッグ、初期化補助スクリプト集 view <-- HTML テンプレートファイル css <-- スタイルシートファイル
設定、初期化ファイルの init.inc.php を編集することで、データ保存ディレクトリの位置などが変更可能です。特にデータディレクトリは、デフォルトのままでは、外部からアクセスされる可能性などもありますので、Web 上からアクセスできない別の場所に移動させておく方が安全です。
例えば、設定、ログデータ保存ディレクトリを上位ディレクトリに移動し、wwwcheck_data というディレクトリにしたい場合は、以下のようにディレクトリを移動した後、init.inc.php を編集します。
$ cd wwwcheck $ mv data ../wwwcheck_data $ vi init.inc.php
init.inc.php の $data_dir
定数の定義の部分を
$data_dir = $self_dir . 'data/';
以下のように変更します。
$data_dir = $self_dir . '../wwwcheck_data/' );
wwwcheck.php 0.2 以降ではデータ保存に、SQLite を使用できます(全てのデータを SQLite に保存するわけではありません)。デフォルトのファイルによる保存は、更新チェックを行う件数が増えると、速度が落ちていきますが、SQLite を使用すると、速度の問題はかなり改善されます。
SQLite は、PHP4 では PECL として提供されています(PHP5 からは、PHP 内に組み込まれています)。Unix 系の OS では、インストールは以下のように、pear
コマンドを使用してください(pear
コマンドの実行には root 権限が必要です)。Windows でも SQLite は使用できるようですが、試していませんので説明は省略します。
$ sudo pear install sqlite
SQLite をインストールした後、テーブルの作成とファイルに保存されているデータの変換を行います。以下のコマンドを実行してください。
$ php /home/user/public_html/wwwcheck/misc/SQLite/createdb.php
コマンドの実行が終わると、データ保存ディレクトリの item ディレクトリの下に、SQLite 用のデータベース(data.sqlite)が作成されています。
次に、init.inc.php の以下の行を変更してください。
define( 'SAVE_HANDLE', 'File' );
以下のように、File
になっている部分を SQLite
に変更します。
define( 'SAVE_HANDLE', 'SQLite' );
SQLite データベースを作成すると、data/item ディレクトリにある、http から始まるファイルは不要になりますので、削除しても問題ありません。
もし、データの管理を SQLite
から File
に戻したい場合、以下のコマンドを実行することで SQLite データベースの内容を File の形式に戻すことができます。
$ php /home/user/public_html/wwwcheck/misc/SQLite/dumpfile.php
ほぼ、SQLite と同じように、PEAR DB を使用することもできるようにしたのですが、あまりテストしていない上に、SQLite と PostgreSQL しか動作を確認していません。不具合がある可能性がありますので、バグ修正できる自信がない場合はあまり使用しない方が良いと思います。
PostgreSQL を使用する場合、wwwcheck
という名前のデータベースを作成し、テーブル作成スクリプトを実行します。データベースの文字コードは UTF-8 にしてください。
$ createdb -E UTF-8 wwwcheck $ php /home/user/public_html/wwwcheck/misc/PEAR_DB/createdb.php
次に、init.inc.php の以下の部分で、SAVE_HANDLE
の定数を PEAR_DB
に変更し、DSN
を記述してください。
define( 'SAVE_HANDLE', 'PEAR_DB' ); if ( SAVE_HANDLE === 'PEAR_DB' ) { define( 'DSN', 'pgsql://user:pass@unix()/wwwcheck' ); }
データの管理を PEAR_DB
から File
に戻したい場合、以下のコマンドを実行します。
$ php /home/user/public_html/wwwcheck/misc/PEAR_DB/dumpfile.php
初期設定では、出力される文字コード設定は UTF-8 になっていますが、変更することも可能です。
init.inc.php の以下の個所の $mb_output_enc
を変更してください('UTF-8' の部分を書き換えるのではなく、$conf 以降の部分を削除して書き換えてください)。
$mb_output_enc = $conf->get( 'mb_output_enc', 'UTF-8' );
$mb_output_enc = 'SJIS';
$mb_output_enc = 'EUC-JP';
コマンドラインから更新チェックを行うことも可能です。コマンドライン(CLI)版 PHP で update.php を実行してください。
$ php update.php
ただし、ファイルの所有者の違いによるデータの書込み権限については注意してください。
cron への登録を行い、定期的に更新チェックを行うには、以下のように、crontab
コマンドで登録します。-e
一日一回、午前 6時に更新チェックを行う場合は以下のように登録します( /home/user/public_html/wwwcheck/ にインストールしている場合)。
00 06 * * * /usr/local/bin/php /home/user/public_html/wwwcheck/update.php
コマンドラインから実行するため、実行ユーザについては、十分に気をつけてください。データ保存ディレクトリに書き込み権限がないユーザが実行した場合、エラーが発生します。
仕様や分かりにくい部分についてメモしておきます。この部分も無視して問題ありません。
静的なページの場合、HTTPD が出力する HTTP のレスポンスヘッダに Last-Modifed
が付いていることが多いのですが、動的に生成されるページでは、Last-Modifed
が含まれていることはあまりありません。また、一部のページでは、変更などはない場合でもアクセスした時間を Last-Modifed
として出力することがあるようです。このため、動的に生成されたページの場合、正確な更新日時を取得することはできません。
このツールでは、更新日時は以下のように取得しています。更新日時の取得処理が気になる場合は参考にしてください。ただし、今後、この処理は変更される可能性があります。
Last-Modifed
が含まれていた場合
初回時、または、前回に取得したページ内容から変更がある場合は HTTP ヘッダに含まれていた Last-Modifed
の時間を更新日時とする。
前回に取得したページ内容から変更がない場合、前回取得した更新日時を今回の更新日時とする(更新時間を変更しない)。もし、前回取得した更新日時が正しく取得できなかった場合、前回にアクセスし、ログを保存した時間を更新日時とする。
Last-Modifed
が含まれていなかった場合、または、含まれていたが、正しく更新時間を取得できなかった場合
初回時、または、前回に取得したページ内容から変更がある場合はアクセス時(HTTP ヘッダの Date
)を更新日時とする。HTTP ヘッダに Date
が含まれていない場合、現在の時間を更新日時とする。
前回に取得したページ内容から変更がない場合、前回取得した更新日時を今回の更新日時とする(更新時間を変更しない)。もし、前回取得した更新日時が正しく取得できなかった場合、前回にアクセスし、ログを保存した時間を更新日時とする。ログからの時間が何らかの原因で取得できなかった場合、現在の時間を更新日時とする。
広告などを削除した後に、ページが更新されたかを判断することができるようにするために、フィルタを設定することができます。パターンにマッチした URI と、取得した文書の中でマッチしたフィルタパターンを削除することになっていますが、Perl 互換の正規表現を書くのは難しいかもしれません。分からない場合は、使わない方が安全です。
以下のようなブックマークレットをブックマークに登録しておくと、現在表示しているページの登録がを簡単にできます(ホスト名とパス名は環境に応じて変更する必要があります)。ブックマークレットについては、はてなダイアリーのブックマークレットの説明を参照してください。
javascript:document.location='http://localhost/wwwcheck/?mode=config&link='+escape(document.location)
基本的には以下のどれかの方法でバージョンアップを行ってください。
例えば、前のバージョンが /path/to/path/wwwcheck/ にインストールされている状態で、0.42 へバージョンアップする場合は以下のように行ってください。
$ cd /path/to/path/ $ tar jxvf wwwcheck-0.42.tar.bz2 $ cp -r wwwcheck/data wwwcheck-0.42/ $ mv wwwcheck wwwcheck.old $ mv wwwcheck-0.42 wwwcheck
古いバージョンが不要であれば、wwwcheck.old を削除してください。
同様に、前のバージョンが /path/to/path/wwwcheck/ にインストールされている状態で、0.42 へバージョンアップする場合は以下のように行ってください。
$ cd /path/to/path/ $ tar jxvf wwwcheck-0.42.tar.bz2 $ cp -r wwwcheck-0.42 wwwcheck
適当な場所に必要なバージョンの Patch をダウンロードした後、patch
コマンドを使用して Patch を適用してください。
例えば、前のバージョンが 0.41 で、/path/to/path/wwwcheck/ にインストールされている場合、0.42 へバージョンアップする場合は以下のように行ってください。
$ cd /path/to/path/wwwcheck/ $ patch -p1 < /path/to/path/wwwcheck_0.41_0.42.patch
上記の方法でバージョンアップを行ってください。
セキュリティ問題の見直しを行いました。
register_globals が有効になっている場合、ライブラリを直接狙ってクロスサイトスクリプティングが可能だった問題を修正しました。
潜在的にセキュリティ問題がありそうな部分について修正を行いました。
RSS 1.0 を出力可能にしてみました。
細かいバグ修正など。
致命的なバグ(更新チェック実行時に、URI に & が含まれている登録サイトの & 以下が削除されてしまう問題)を修正しました。報告してくださった方、どうもありがとうございました。
クロスサイト・スクリプティングが可能でしたので該当部分のコードを修正しました。
その他、細かいバグの修正と問題がありそうなコードの修正を行いました。
使用していないファイルを削除しました。
PHP 4.4.0 で修正されたリファレンス関連のバグの関係で、大量のエラーが表示されるようになってしまいましたので、エラーが発生する部分のコードを修正しました。
CSRF 処理を修正し、複数のウインドウを開いていても処理が続けられるようにしました。
その他、細かいバグ修正を行いました。
HTTP ヘッダに ETag フィールドが含まれていた場合、次の更新チェック時に、"If-Modified-Since" と "If-None-Match" を HTTP のリクエストヘッダに含めるようにしました。ETag を出力するページで、前回のチェック時から更新がないページの取得が高速になります。
設定画面で HTTP のレスポンスヘッダのステータスコード一覧を表示する「ステータス一覧」ページを追加しました。
設定画面の「表示・デフォルト値設定」で表示期間、訪問後の項目についてのデフォルト値設定を変更できるようにしました。
その他、バグ修正などを行いました。
CSRF 問題への対処を行いました。
設定画面の変更を行いました。
一覧表示での表示期間の選択フォームを追加しました。
以前のバージョンを削除しました。
デザイン変更を行いました。
スタイルシートの選択機能を追加を追加しました。
いくつかのバグ修正を行いました。
ドキュメントを書きました
ドキュメントは全然進んでいません。
ドキュメントは作成中です。