PHPでは、 MD5_FILE()は、指定されたファイルコンテンツのMD5ハッシュ値を計算するための非常に実用的な機能です。基本的な構文は次のとおりです。
md5_file(string $filename, bool $binary = false): string|false
この機能は、ファイルの検証、キャッシュメカニズム、ファイルの整合性検証、その他のシナリオの処理において非常に一般的です。ただし、実際の使用中に、開発者は混乱する問題に遭遇する可能性があります。ファイルが存在し、パスは正しいですが、 MD5_File()はFALSEを返します。これは通常、ファイルの許可の問題によって引き起こされます。この記事では、その原因、一般的なシナリオ、ソリューションを詳細に分析します。
MD5_FILE()は、 MD5操作を実行するために、ファイルの内容全体を内部的に読み込もうとします。したがって、PHPスクリプトの許可がターゲットファイルを読み取るのに十分でない場合、関数はfalseを返します。
md5_file()の場合、ファイルには「読み取り可能な権限」が必要です。これには、次の寸法が含まれます。
ファイル自体は、現在の実行ユーザー( www-dataなど)が読み取る必要があります。
すべての上位レベルのディレクトリには、PHPがパスにアクセスできるように、「実行許可」(つまり、「入力」することができます)が必要です。
Selinux、Apparmorなどのシステムセキュリティモジュールもアクセス権に影響を与える可能性があります。
ファイルの許可が600 (所有者の読み取り可能で書き込み可能)の場合、PHP実行ユーザーがファイルの所有者ではない場合、ファイルは読み取られません。
-rw------- 1 root root 1024 May 28 10:00 secret.txt
PHPがwww-dataユーザーとして実行されている場合、上記のファイルを読み取ることができず、md5_file()は失敗します。
ファイル自体が許可を読み取ったとしても、ディレクトリの許可がPHPの入力を許可していない場合、ファイルにアクセスできません。
drwx------ 2 user user 4096 May 28 10:00 /var/private/
この場合、ファイルが644に設定されていても、PHPは/var/private/secret.txtにアクセスできません。
一部のLinuxシステムには、SELINUXまたはAppARMORが有効になっている場合があり、ファイル許可が「正常」であると思われていても、システムポリシーによって制限される場合があります。
次のコマンドを使用して、selinuxの制限を確認できます。
ls -Z /path/to/file
ターゲットファイルがPHPユーザーに許可を読み取っていることを確認してください。最も簡単な方法は、ファイルアクセス許可を644に設定し、PHPユーザーがディレクトリに権限を持つことを確認することです。
chmod 644 /path/to/file.txt
chown www-data:www-data /path/to/file.txt
次のPHPコードを介して、現在のエグゼキューターユーザーを一時的にデバッグできます。
echo get_current_user(); // または使用します posix_geteuid()
ユーザーがターゲットファイルとディレクトリにアクセスする許可があることを確認してください。
md5_file()を呼び出す前に、直接エラーを回避するためにファイルが読み取り可能かどうかを確認します。
$file = '/var/data/file.txt';
if (is_readable($file)) {
$hash = md5_file($file);
echo "Hash: $hash";
} else {
echo "ファイルは読み取りできません,許可を確認してください";
}
Selinux対応システムを使用している場合は、 CHCONコマンドを介してコンテキストを変更する必要がある場合があります。
chcon -t httpd_sys_content_t /path/to/file.txt
または一時的にSelinuxテストをシャットダウンします(生産環境には推奨されません):
setenforce 0
https://m66.net/files/check.txtなどのCDNまたはリモートアドレスを使用している場合、 MD5_FILE()も失敗します。ローカルファイルパスのみを処理でき、URLを処理できないためです。リモートファイルは最初にダウンロードしてから、次の方法を使用して処理できます。
error_reporting = E_ALL
display_errors = On