[PHP]filesize関数の使い方を完全解説!ファイルサイズ取得のベストプラクティス

PHP

こんにちは!今回はPHPのfilesize関数について、基本から応用まで詳しく解説していきます。

1. filesize関数の基本

構文と戻り値

int filesize ( string $filename )
  • 成功時:ファイルサイズ(バイト単位)を返す
  • 失敗時:false を返す
  • 2GB以上のファイルの場合は、32ビットシステムで問題が発生する可能性あり

2. 基本的な使用例

シンプルな使用例

$filename = 'example.txt';
$size = filesize($filename);
echo "ファイルサイズ: " . $size . " bytes";

読みやすい形式での表示

function formatFileSize($bytes) {
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];

    $bytes = max($bytes, 0);
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
    $pow = min($pow, count($units) - 1);

    $bytes /= (1 << (10 * $pow));

    return round($bytes, 2) . ' ' . $units[$pow];
}

$filename = 'large_file.zip';
$size = filesize($filename);
echo "ファイルサイズ: " . formatFileSize($size);

3. 実践的な使用例

ディレクトリ内の全ファイルサイズ取得

function getDirectorySize($path) {
    $total_size = 0;
    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path),
        RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($files as $file) {
        if ($file->isFile()) {
            $total_size += $file->getSize();
        }
    }

    return $total_size;
}

// 使用例
$dir_path = './uploads';
$total = getDirectorySize($dir_path);
echo "ディレクトリ総サイズ: " . formatFileSize($total);

ファイルサイズの監視と制限

function checkFileUploadSize($file, $max_size = 5242880) { // 5MB
    if (!file_exists($file)) {
        throw new Exception('ファイルが存在しません');
    }

    $size = filesize($file);

    return [
        'filename' => basename($file),
        'size' => $size,
        'formatted_size' => formatFileSize($size),
        'is_allowed' => $size <= $max_size,
        'max_size' => formatFileSize($max_size)
    ];
}

ファイルサイズのキャッシング

class FileSizeCache {
    private static $cache = [];
    private static $cache_duration = 300; // 5分

    public static function getSize($filename) {
        $key = realpath($filename);

        if (!isset(self::$cache[$key]) || 
            (time() - self::$cache[$key]['time']) > self::$cache_duration) {

            self::$cache[$key] = [
                'size' => filesize($filename),
                'time' => time()
            ];
        }

        return self::$cache[$key]['size'];
    }
}

4. エラーハンドリング

包括的なエラーハンドリング

function safeFileSize($filename) {
    try {
        // ファイルの存在確認
        if (!file_exists($filename)) {
            throw new Exception('ファイルが存在しません: ' . $filename);
        }

        // 読み取り権限の確認
        if (!is_readable($filename)) {
            throw new Exception('ファイルを読み取れません: ' . $filename);
        }

        $size = filesize($filename);
        if ($size === false) {
            throw new Exception('ファイルサイズの取得に失敗しました');
        }

        return [
            'success' => true,
            'size' => $size,
            'formatted_size' => formatFileSize($size),
            'file' => basename($filename)
        ];

    } catch (Exception $e) {
        error_log('ファイルサイズエラー: ' . $e->getMessage());
        return [
            'success' => false,
            'error' => $e->getMessage()
        ];
    }
}

5. パフォーマンス最適化

大きなディレクトリの処理

function getDirectorySizeOptimized($path) {
    $total_size = 0;
    $count = 0;
    $start_time = microtime(true);

    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path),
        RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($files as $file) {
        if ($file->isFile()) {
            $total_size += $file->getSize();
            $count++;

            // 処理時間が長すぎる場合は中断
            if (microtime(true) - $start_time > 30) { // 30秒
                throw new Exception('処理時間が長すぎます');
            }
        }
    }

    return [
        'total_size' => $total_size,
        'formatted_size' => formatFileSize($total_size),
        'file_count' => $count,
        'execution_time' => microtime(true) - $start_time
    ];
}

6. 実装のベストプラクティス

  1. 大きなファイルの処理
function handleLargeFile($filename) {
    // メモリ制限の一時的な引き上げ
    ini_set('memory_limit', '256M');

    $size = filesize($filename);
    if ($size > 2147483647) { // 2GB超
        // 代替手段を使用
        $size = trim(shell_exec('stat -f %z ' . escapeshellarg($filename)));
    }

    return $size;
}
  1. メモリ使用量の最適化
function getFileSizeEfficient($filename) {
    if (PHP_INT_SIZE === 4) { // 32ビットシステム
        $size = trim(shell_exec('stat -f %z ' . escapeshellarg($filename)));
    } else {
        $size = filesize($filename);
    }

    return $size;
}

まとめ

filesize関数は、シンプルながら以下の点に注意が必要です:

  1. 大きなファイルの処理(特に32ビットシステム)
  2. エラーハンドリング
  3. パフォーマンスとメモリ使用量
  4. キャッシュの活用
  5. 適切な権限管理

これらの点に気をつけることで、より信頼性の高いファイルサイズ処理が実現できます。

ご質問やご不明な点がありましたら、お気軽にコメントください!

タイトルとURLをコピーしました