PHP Shade 2021年06月19日 02:29   編集
Shadeプラグイン・スクリプト検索もレスポンシブ対応にしようかなと思って、久しぶりにCGIファイルを見てみたら、いろいろ他にも気になる部分が目について、結局ゼロからPHPで書き直すことにした。ちょこちょこ修正しているとはいえ、元はなんせ20年も前に書いたものだからなー。

スムーズに移行できるようログは旧CGIで作成したものをそのまま流用するつもりだったが、データを1個のファイルにすべて保存する形式にしていたのがどうも気になる。ダウンロードカウントもこのファイルに書き込む方式だったので、アクセスがあるたびにデータファイルを書き換える処理をしていたことになる。最初のころしょっちゅうログファイルが壊れていたのはこれが原因だったのかもしれない。
さすがにこれはないだろうと、まず新しいPHPプログラムでアクセスすると旧データファイルを扱いやすいデータ形式に書き換えることにする。登録内容1件ごとにファイルを作成することにして、ダウンロードは別ファイルでカウントすることにする。新方式のデータファイルを作成したら旧データファイルにはアクセスしないことにした。 旧CGIは文字コードはSJISを使用していたが、新プログラムではUTF-8で書き、ログファイルの文字コードもUTF-8に変換する。

それと旧CGIでは処理ごとに複数のCGIを組み合わせて使っていたため、操作が面倒な部分があった。
まずデベロッパーの登録は本体とは別の登録専用CGIで行っていたので、登録用CGIで新規登録すると、メールで仮パスワードが送られ、その仮パスワードで登録用CGIにログインし、そこでデベロッパーが希望するパスワードに変更するという結構面倒なことをしていた。この仕組のためメールアドレスを登録しないとデベロッパー登録できないことになっていた。
また自分のホームページを持っていないデベロッパーのために、ファイルをアップロードした上で公開できるようにしていたのだが、ファイルをアップロードするCGIも本体の検索CGIとは別なので、いったんファイルをアップロードした上でさらに検索CGIに登録するという二度手間がかかっていた。
複数のCGIで処理を分担しているため、わかりにくい上にデベロッパーに負担を強いる仕様になっていたということだ。
今回の修正では検索、デベロッパーの新規登録、ファイルのアップロードすべて同じPHPプログラムで一括して行うことにした。これでメールアドレスを登録しなくてもデベロッパーの新規登録ができるようになった。
ファイルをアップロードする場合は、登録フォームから直接ツールをアップロードすれば、そのまま登録できるようにした。
登録専用CGIで管理していた登録者のパスワード情報は暗号化したディレクトリ上に暗号化して保存されていたがこれはそのまま流用することにする。

旧CGIの動作が重い原因のひとつは、アクセスするたびにリンク切れをチェックしていたことがあると思う。登録URLをすべてチェックしたら、とんでもなく時間がかかるので、CGIを動かすたびにランダムに2~3件ぐらいチェックしていたのだが、それでもかなり重くなっていたようだ。
PHPでは、高速にリンクチェックできるcURL関数、その中でも複数のアドレスに一気にアクセスできるというcurl_multi系の関数を使ってチェックするようにしたら、200個以上のURLが2秒ぐらいでチェックできるようになった。これなら他の処理のついでに数件のリンクチェックを行ってもほとんど問題ないだろう。

・・・と思っていたが、やはりちょっと重くなるのが気になる。
リンクチェックについてはトップページを表示したときに数件のリンクチェックを行うようにしていたが、回数を少なくしてもやはり若干重くなるのは変わらないのでこれはやめることにした。とはいってもリンクチェックは定期的に行いたいので、サーバーのCRON[1]機能で実行することにした。検索スクリプトのリンクチェックを行うURLをCRONで実行しようとしたが、クエリパラメータつきのURLは登録できないようなので、リンクチェックだけを行うPHPを別途追加した。このPHPへはトップページにリンクも張ったので、いつでも手動でリンクチェックすることもできる。

リンク切れについて

この検索サイトではメンテナンスフリーのため、リンク切れを検出したら登録を解除することにしているが、そのアルゴリズムを整理しておく。
curl_multiでhttpコードが404だったらリンク切れと判断してリンク切れカウントファイルに1を書き込む。このカウントファイルはリンク切れ検出の回数を記録するもので、リンク切れを検出するたびに1を追記する。最初にリンク切れを検出した日時の情報もほしいところだが、PHPではファイルの作成日時を取得する手段がなさそうなので、最初にリンク切れを検出したときだけカウントファイルとは別にファイルを作成することにする。一応time()で取得したエポック秒を記録するが、通常はファイルの中身は確認せずにfilemtimeで取得した更新時間が最初のリンク切れ検出時間と言うことになる。
リンク切れは一時的なものだったり、誤検出の可能性もあるので、リンク切れ検出回数が一定回数に達して、最初のリンク切れ検出時間から一定時間経過したら、リンク切れと判断してリンク切れ確定ファイルを作成する。リンク切れカウントファイルや検出時間記録ファイル、そしてこのリンク切れ確定ファイルは、一度でもリンク接続が確認されたら削除する。

検索プログラムでは、リンク切れ確定ファイルが作成されている登録については、トップページに表示するとともに、検索結果にもリンク切れであることを表示する。

そしてリンク切れ確定からさらに一定時間が経過したら(30日ぐらい?)、登録内容を削除する。
[1]指定時間に指定コマンドを実行する機能
counter:14,565