ホームページ >バックエンド開発 >PHPチュートリアル >PHPマスター|ファイルの完全性を監視します
キーポイント
hash_file()
関数を使用して、監視用のファイル構造構成ファイルを作成できます。各ファイルのハッシュ値は、後で比較するために保存して、変更を検出できます。 file_path
file_hash
PHPのクラスを使用して、ファイルツリーを通過し、比較のためにハッシュを収集できます。その後、これらのハッシュを使用してRecursiveDirectoryIterator
integrity_hashes
array_diff_assoc()
ウェブサイトを管理するときに次の状況を解決する方法を検討してください:
ファイル
を誤って追加、変更、または削除します関数を使用することにしました。さまざまな異なるハッシュアルゴリズムを提供します。これにより、後で変更することを決定した場合にコードを簡単に変更できます。ハッシュは、パスワード保護からDNAシーケンスまで、さまざまなアプリケーションで使用されます。ハッシュアルゴリズムは、データを固定サイズの再現可能な暗号化された文字列に変換することにより機能します。データをわずかに変更しても、非常に異なる結果が生じるように設計されています。 2つ以上の異なるデータが同じ文字列結果を生成する場合、「競合」と呼ばれます。各ハッシュアルゴリズムの強度は、衝突の速度と確率によって測定できます。私の例では、SHA-1アルゴリズムは高速で、競合の可能性が低く、広く使用され、完全にテストされているため、SHA-1アルゴリズムを使用します。もちろん、他のアルゴリズムを調査し、好きなアルゴリズムを使用することを歓迎します。ファイルのハッシュ値を取得した後、後で比較するために保存できます。後でファイルのハッシュが以前と同じハッシュ文字列を返さない場合、ファイルが変更されたことがわかります。
hash_file()
データベース
最初に、ファイルのハッシュ値を保存するためにベーステーブルをレイアウトする必要があります。次のパターンを使用します:
CREATE TABLE integrity_hashes ( file_path VARCHAR(200) NOT NULL, file_hash CHAR(40) NOT NULL, PRIMARY KEY (file_path) );
file_path
ストレージサーバー上のファイルへのパスは、値が常に一意であるため(2つのファイルがファイルシステムで同じ場所を占有できないため)、それが私たちの主キーです。最大長さを200文字に指定しました。これにより、ファイルパスが長くなるようになりました。 file_hash
ファイルのハッシュ値を保存します。これは、SHA-1 40文字の16進数文字列になります。
ファイルを収集します
次のステップは、ファイル構造の構成ファイルを構築することです。ファイルの収集を開始するパスを定義し、ファイルシステムのブランチ全体を上書きし、オプションで特定のディレクトリまたはファイル拡張子を除外するまで、各ディレクトリを再帰的に反復します。ファイルツリーを通過するときに必要なハッシュ値を収集し、データベースに保存するか比較のために収集します。 PHPは、ファイルツリーを通過するいくつかの方法を提供します。 RecursiveDirectoryIterator
<?php define("PATH", "/var/www/"); $files = array(); // 要获取的扩展名,空数组将返回所有扩展名 $ext = array("php"); // 要忽略的目录,空数组将检查所有目录 $skip = array("logs", "logs/traffic"); // 构建配置文件 $dir = new RecursiveDirectoryIterator(PATH); $iter = new RecursiveIteratorIterator($dir); while ($iter->valid()) { // 跳过不需要的目录 if (!$iter->isDot() && !in_array($iter->getSubPath(), $skip)) { // 获取特定文件扩展名 if (!empty($ext)) { // PHP 5.3.4: if (in_array($iter->getExtension(), $ext)) { if (in_array(pathinfo($iter->key(), PATHINFO_EXTENSION), $ext)) { $files[$iter->key()] = hash_file("sha1", $iter->key()); } } else { // 忽略文件扩展名 $files[$iter->key()] = hash_file("sha1", $iter->key()); } } $iter->next(); }
配列で同じフォルダーを2回参照したことに注意してください。特定のディレクトリを無視することを選択したからといって、イテレーターがあなたのニーズに応じてすべてのサブディレクターを無視していることを意味するわけではありません。 $skip
クラスは、複数の方法へのアクセスを提供します:logs
RecursiveDirectoryIterator
valid()
isDot()
ファイルポインターが現在配置されているフォルダー名に戻りますgetSubPath()
フルパスとファイル名を返してくださいkey()
ループを再起動しますnext()
さらに多くの方法がありますが、ほとんどの場合、上記のリストはすべて必要なメソッドですが、配列に記入する必要があります。
getExtension()
pathinfo()
構成ファイルを構築した後、データベースを簡単に更新できます。 $files
<code>Array ( [/var/www/test.php] => b6b7c28e513dac784925665b54088045cf9cbcd3 [/var/www/sub/hello.php] => a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa [/var/www/sub/world.php] => da39a3ee5e6b4b0d3255bfef95601890afd80709 )</code>
違いを確認してください
<?php $db = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD); // 清除旧记录 $db->query("TRUNCATE integrity_hashes"); // 插入更新的记录 $sql = "INSERT INTO integrity_hashes (file_path, file_hash) VALUES (:path, :hash)"; $sth = $db->prepare($sql); $sth->bindParam(":path", $path); $sth->bindParam(":hash", $hash); foreach ($files as $path => $hash) { $sth->execute(); }
ディレクトリ構造用の新しい構成ファイルを構築する方法と、データベース内のレコードを更新する方法がわかりました。次のステップは、電子メール通知を備えたCronジョブ、管理インターフェイス、または他のものなど、何らかの実際のアプリケーションに結合することです。変更を気にせずに変更されたファイルのリストを収集したい場合、最も簡単な方法は、データベースからデータをと同様の配列に抽出し、PHPの関数を使用して不要なコンテンツを削除することです。
CREATE TABLE integrity_hashes ( file_path VARCHAR(200) NOT NULL, file_hash CHAR(40) NOT NULL, PRIMARY KEY (file_path) );この例では、
とは異なり、2つの空のファイルには同じハッシュ値があるなど、競合するときに重要です。これは重要です。さらに一歩進めたい場合は、簡単なロジックを追加して、ファイルがどのように影響を受けるか、削除、変更、または追加されているかどうかを正確に判断できます。 $diffs
array_diff()
array_diff_assoc()
データベースで結果を通過すると、複数のチェックを行います。まず、
<?php define("PATH", "/var/www/"); $files = array(); // 要获取的扩展名,空数组将返回所有扩展名 $ext = array("php"); // 要忽略的目录,空数组将检查所有目录 $skip = array("logs", "logs/traffic"); // 构建配置文件 $dir = new RecursiveDirectoryIterator(PATH); $iter = new RecursiveIteratorIterator($dir); while ($iter->valid()) { // 跳过不需要的目录 if (!$iter->isDot() && !in_array($iter->getSubPath(), $skip)) { // 获取特定文件扩展名 if (!empty($ext)) { // PHP 5.3.4: if (in_array($iter->getExtension(), $ext)) { if (in_array(pathinfo($iter->key(), PATHINFO_EXTENSION), $ext)) { $files[$iter->key()] = hash_file("sha1", $iter->key()); } } else { // 忽略文件扩展名 $files[$iter->key()] = hash_file("sha1", $iter->key()); } } $iter->next(); }に表示されるかどうかを確認します。そうでない場合は、ファイルが削除されている必要があります。次に、ファイルが存在するがハッシュが一致しない場合、ファイルが変更されているか変更されていない必要があります。各チェックを
と呼ばれる一時配列に保存し、最後に、array_key_exists()
の数値がデータベースの数値よりも大きい場合、残りのチェックされていないファイルが追加されていることがわかります。完了したら、$files
は空の配列であるか、多次元配列の形で見つかった違いを含んでいます。これは次のようになります。
$tmp
$files
よりユーザーフレンドリーな形式(管理インターフェイスなど)で結果を表示するには、たとえば結果を反復し、箇条書きリストとして出力できます。 $diffs
<code>Array ( [/var/www/test.php] => b6b7c28e513dac784925665b54088045cf9cbcd3 [/var/www/sub/hello.php] => a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa [/var/www/sub/world.php] => da39a3ee5e6b4b0d3255bfef95601890afd80709 )</code>を保存することを選択できます)、または違いを承認しない場合は、必要に応じて処理できます。
<?php $db = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD); // 清除旧记录 $db->query("TRUNCATE integrity_hashes"); // 插入更新的记录 $sql = "INSERT INTO integrity_hashes (file_path, file_hash) VALUES (:path, :hash)"; $sth = $db->prepare($sql); $sth->bindParam(":path", $path); $sth->bindParam(":hash", $hash); foreach ($files as $path => $hash) { $sth->execute(); }概要
$files
(元のテキストのFAQ部分はここで保持する必要があります。なぜなら、この部分の内容はコード部分とは関係がなく、補足的な説明に属し、擬似オリジニティのカテゴリに該当しないため)
以上がPHPマスター|ファイルの完全性を監視しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。