md5_file() は、ファイルの中身から md5(32 けたの 16 進数の値)を求める PHP の関数です。ファイルが 1 文字でも違えば別の値になるので、配られているファイルと同じかどうか、書き換えられていないかを確認するときに使います。
書き方
md5_file( string $filename, bool $binary = false ): string|false
$filename:md5 を求めるファイルのパス$binary:true なら、32 けたの文字ではなく、16 バイトのバイナリで返す。ふつうは false(書かない)- 戻り値:md5 の文字列。ファイルが読めないときは false
| 関数 | 使い分け |
|---|---|
| md5_file( $file ) | ファイルの md5。ファイルを少しずつ読みながら求める |
| md5( $string ) | 文字列の md5。ファイルに使うと、先に file_get_contents() で丸ごと読むことになる |
使い方の例
作業環境(PHP 8.3・WordPress 7.1.3)で試した結果を、コメントに書いています。
大きなファイルでもメモリを食わない
50MB のファイルで、md5_file() と md5( file_get_contents() ) を比べました。値は同じですが、メモリの使う量が大きく違います。
<?php $file = __DIR__ . '/big.bin'; // 50MB のファイル echo md5_file( $file ); // 25e317773f308e446cc84c503a6d1f85 echo md5( file_get_contents( $file ) ); // 25e317773f308e446cc84c503a6d1f85(同じ値) // メモリの使う量(memory_get_peak_usage( true ) を、それぞれ別の実行で測った) // md5_file() → 2.0MB // md5( file_get_contents() ) → 54.0MB(ファイルを丸ごと読むので、ファイルの大きさの分が増える)
読めないときは false
<?php
$hash = md5_file( __DIR__ . '/no-such-file.txt' );
var_dump( $hash ); // bool(false)(PHP の警告も出る)
// false と、中身が空のファイルの md5 を取り違えないよう、=== で比べる
if ( false === $hash ) {
error_log( 'ファイルが読めない' );
}
echo md5_file( __DIR__ . '/empty.txt' ); // d41d8cd98f00b204e9800998ecf8427e(空のファイル。md5( '' ) と同じ)
ファイルが書き換えられていないかを確認する
WordPress.org は、本体とプラグインのファイルごとの md5 を配っています。その値と比べると、ファイルが配られたものと同じかが分かります。作業環境で、プラグインの readme.txt に 1 行足して試しました(試したあとは、元のファイルに戻して md5 が同じになったことを確認しています)。
<?php // WordPress.org が配っている md5 と比べて、ファイルが書き換えられていないかを確かめる $want = '5027401feb911a5db99e2ca0bce73319'; // チェックサムの JSON にある md5 $file = WP_PLUGIN_DIR . '/my-org-plugin/readme.txt'; echo md5_file( $file ) === $want ? '同じ' : '変わった'; // 同じ file_put_contents( $file, "\n# test line\n", FILE_APPEND ); // わざと 1 行足すと echo md5_file( $file ) === $want ? '同じ' : '変わった'; // 変わった(9e6782b8d470404fb4e055b4eee0786d)
バイナリで受け取る
<?php // $binary を true にすると、16 バイトのバイナリで返る echo strlen( md5_file( __DIR__ . '/big.bin' ) ); // 32 echo strlen( md5_file( __DIR__ . '/big.bin', true ) ); // 16 echo bin2hex( md5_file( __DIR__ . '/big.bin', true ) ); // 25e317773f308e446cc84c503a6d1f85
気をつけること
- ファイルが読めないと false が返り、PHP の警告も出ます。戻り値は
===で比べてください。==で比べると、思わぬ値と等しいと見なされることがあります。 - md5 は、わざと同じ値になる別のファイルを作る方法が知られています。配られたファイルと同じかを確認する使い方には十分ですが、パスワードの保存や署名には使わず、パスワードは
password_hash()、より強いチェックにはhash_file( 'sha256', $file )を使ってください。 - 多くのファイルに使うと、ファイルを全部読むので時間がかかります。作業環境では、WordPress の本体(4,000 ほどのファイル)を比べるのに、WordPress の読み込みを含めて 1 秒ほどかかりました。サーバーではもっとかかることがあるので、管理画面のページを開くたびに動かすのではなく、WP-Cron などで裏で動かしてください。
- 改行の形(LF と CRLF)や文字コードが違うだけでも、別の値になります。FTP のソフトがテキストのファイルの改行を替えてアップロードしていると、中身は同じでも「変わった」と見えることがあります。

