こんにちは!今回は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. 実装のベストプラクティス
- 大きなファイルの処理
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;
}
- メモリ使用量の最適化
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関数は、シンプルながら以下の点に注意が必要です:
- 大きなファイルの処理(特に32ビットシステム)
- エラーハンドリング
- パフォーマンスとメモリ使用量
- キャッシュの活用
- 適切な権限管理
これらの点に気をつけることで、より信頼性の高いファイルサイズ処理が実現できます。
ご質問やご不明な点がありましたら、お気軽にコメントください!