【PHP8.x】finfo_file関数の使い方

作成日: 更新日:

finfo_file関数は、指定されたファイルの内容を調べて、そのファイルに関する情報を取得する関数です。この関数は、ファイルの拡張子だけでなく、実際の内容に基づいてファイルの種類を判別するため、より正確なファイルタイプの特定が可能です。例えば、拡張子が「.txt」であるファイルが、実際には画像ファイルである場合でも、finfo_file関数は画像ファイルであると判別できます。

この関数を使用するには、まずfinfo_open関数などでfinfoオブジェクトを作成し、そのオブジェクトをfinfo_file関数に渡します。必須の引数として、調べたいファイルのパスを文字列で指定します。オプションで、マジックデータベースのパスを指定することも可能です。

finfo_file関数は、成功した場合、ファイルの情報を文字列で返します。この文字列には、ファイルのMIMEタイプや文字エンコーディングなど、様々な情報が含まれます。エラーが発生した場合は、falseを返します。

finfo_file関数は、アップロードされたファイルの安全性チェックや、ファイルの種類に応じた処理を行う場合に非常に役立ちます。例えば、画像ファイルのみを受け付けるウェブアプリケーションで、悪意のあるユーザーが拡張子を偽装したファイルをアップロードしようとした場合でも、finfo_file関数を使用することで、ファイルの内容を正確に判別し、不正なファイルを排除することができます。システムエンジニアを目指す初心者の方にとって、ファイルの取り扱いに関するセキュリティ対策として、この関数を理解しておくことは重要です。

基本的な使い方

構文(syntax)

finfo_file(finfo $finfo, string $filename, int $flags = FILEINFO_NONE): string|false

引数(parameters)

finfo $finfo, string $filename, int $flags = 0, mixed $context = null

  • finfo $finfo: ファイル情報取得のためのFinfoインスタンス
  • string $filename: ファイルパスを指定する文字列
  • int $flags = 0: ファイル情報の取得方法を指定するフラグ (デフォルトは0)
  • mixed $context = null: コンテキストを指定する (通常はnull)

戻り値(return)

string|false

指定されたファイルからMIMEタイプを文字列で返します。ファイルを開けなかった場合などはfalseを返します。

サンプルコード

PHPでファイルのMIMEタイプを取得する

<?php

/**
 * finfo_file() を使用してファイルのMIMEタイプを取得するサンプル関数です。
 *
 * この関数は、一時的なテキストファイルを作成し、そのファイルのMIMEタイプを特定して表示します。
 * 処理完了後、作成したファイルは自動的に削除されます。
 *
 * @return void
 */
function checkFileMimeType(): void
{
    // 調査対象の一時ファイルを作成します。
    $filename = 'sample.txt';
    $content = 'これはMIMEタイプを調べるためのサンプルテキストです。';
    
    // file_put_contentsは成功時に書き込んだバイト数、失敗時にfalseを返します。
    if (file_put_contents($filename, $content) === false) {
        echo "エラー: 一時ファイル '{$filename}' の作成に失敗しました。\n";
        return;
    }

    try {
        // finfoリソースをオープンします。
        // 第1引数に定数 FILEINFO_MIME_TYPE を指定することで、
        // 'text/plain' や 'image/jpeg' のようなMIMEタイプを取得できます。
        $finfo = finfo_open(FILEINFO_MIME_TYPE);

        if ($finfo === false) {
            echo "エラー: Fileinfo拡張機能の初期化に失敗しました。\n";
            return;
        }

        // finfo_file() を使って、指定したファイルのMIMEタイプを文字列として取得します。
        $mimeType = finfo_file($finfo, $filename);

        // リソースを解放します。
        finfo_close($finfo);

        if ($mimeType !== false) {
            // 取得したMIMEタイプを表示します。
            echo "ファイル名: {$filename}\n";
            echo "MIMEタイプ: {$mimeType}\n"; // 期待される出力: MIMEタイプ: text/plain
        } else {
            echo "エラー: ファイル '{$filename}' のMIMEタイプの取得に失敗しました。\n";
        }
    } finally {
        // 後処理として、作成した一時ファイルを確実に削除します。
        if (file_exists($filename)) {
            unlink($filename);
        }
    }
}

// 作成した関数を実行します。
checkFileMimeType();

?>

このPHPサンプルコードは、finfo_file関数を使ってファイルのMIMEタイプ(種類)を特定する方法を示しています。まず、MIMEタイプを調べるための一時的なテキストファイルを作成します。次に、finfo_open関数を用いてFileinfo拡張機能のリソースを初期化します。この際、FILEINFO_MIME_TYPE定数を指定することで、結果がMIMEタイプ形式(例: "text/plain")となるように設定しています。

finfo_file関数は、第一引数にfinfo_openで取得したFileinfoリソース、第二引数にMIMEタイプを調べたいファイルのパスを受け取ります。この関数は、指定されたファイルのMIMEタイプを示す文字列を返しますが、MIMEタイプの取得に失敗した場合はfalseを返します。サンプルコードでは、取得したMIMEタイプを画面に表示し、その後にfinfo_closeでリソースを解放し、作成した一時ファイルもunlink関数で確実に削除することで、リソースリークや不要なファイル残存を防いでいます。このように、finfo_fileはファイルの種類をプログラムで正確に判別したい場合に利用できる便利な関数です。

finfo_file関数を使う際の注意点です。まず、fileinfo拡張機能がPHPにインストールされ有効になっているか確認してください。finfo_open関数でリソースを初期化する際、FILEINFO_MIME_TYPEを指定することでMIMEタイプのみを取得できます。finfo_file関数は、ファイルのMIMEタイプを文字列で返しますが、失敗するとfalseを返します。戻り値がfalseの場合のエラー処理を必ず実装しましょう。サンプルコードのように、try-finallyブロックを使用し、一時ファイルの削除を確実に行うことが重要です。ファイルパスを直接指定する場合は、セキュリティ上のリスクを考慮し、信頼できるファイルのみを処理するようにしてください。ファイルが存在しない場合や権限がない場合もfalseが返るため、事前に確認しておくと良いでしょう。

PHPでファイルのMIMEタイプを取得する

<?php

// ファイルのMIMEタイプを検出する例

// ファイルパス
$filename = 'example.txt';

// finfoオブジェクトを作成
$finfo = finfo_open(FILEINFO_MIME_TYPE);

if ($finfo) {
    // ファイルのMIMEタイプを取得
    $mime_type = finfo_file($finfo, $filename);

    if ($mime_type !== false) {
        echo "ファイルのMIMEタイプ: " . $mime_type . PHP_EOL;
    } else {
        echo "ファイルのMIMEタイプの取得に失敗しました。" . PHP_EOL;
    }

    // finfoオブジェクトを閉じる
    finfo_close($finfo);
} else {
    echo "finfoの初期化に失敗しました。" . PHP_EOL;
}

?>

このサンプルコードは、PHPのfinfo_file関数を使用して、ファイルのMIMEタイプを検出する方法を示しています。finfo_file関数は、finfoオブジェクトとファイル名を引数に取り、ファイルのMIMEタイプを文字列として返します。MIMEタイプの取得に失敗した場合はfalseを返します。

まず、finfo_open関数を使用してfinfoオブジェクトを初期化します。この際、FILEINFO_MIME_TYPEフラグを指定することで、MIMEタイプの検出に特化したfinfoオブジェクトを作成できます。

次に、finfo_file関数に、初期化したfinfoオブジェクトとファイル名を渡します。この関数は、指定されたファイルの内容を解析し、そのファイルのMIMEタイプを返します。

サンプルコードでは、finfo_file関数の戻り値がfalseでないか確認し、正常にMIMEタイプを取得できた場合に、その値を画面に出力します。MIMEタイプの取得に失敗した場合は、エラーメッセージを表示します。

最後に、finfo_close関数を使用して、使用済みのfinfoオブジェクトを解放します。これは、システムリソースを適切に管理するために重要です。finfo_open関数が失敗した場合もエラーメッセージを表示します。 この例では、'example.txt'というファイルが同一ディレクトリに存在することを前提としています。存在しない場合は、MIMEタイプの取得に失敗します。

FileinfoエクステンションがPHPで有効になっているか確認してください。無効な場合、finfo_file関数は機能しません。

finfo_openfinfo_fileは、処理失敗時にfalseを返します。そのため、サンプルコードのように必ず戻り値をチェックし、適切なエラー処理を記述しましょう。

finfo_openで開いたリソースは、処理後にfinfo_closeで忘れずに解放してください。これにより、システムリソースを適切に管理できます。

指定するファイルパスは、PHPが実行されている環境から読み取り権限を持つ必要があります。もしユーザーからの入力値をファイルパスとして利用する場合は、セキュリティ確保のため厳重なパス検証が必要です。

【PHP8.x】finfo_file関数の使い方 | いっしー@Webエンジニア