Kotchasan Framework Documentation
File Class - File and Directory Management
File Class - File and Directory Management
The File class provides utilities for managing files and directories, including copying, listing, creating, and removing directories.
Namespace
Kotchasan\FileOverview
File class provides:
- Copy entire directories recursively
- Get file extensions
- List files in directories and subdirectories
- Create directories with permissions
- Remove directories and all contents
API Reference
copyDirectory()
Copy directory and all contents recursively
public static function copyDirectory(string $sourceDir, string $destDir): voidParameters:
$sourceDir- Source directory path (must have trailing/)$destDir- Destination directory path (must have trailing/)
Returns: void
Example:
use Kotchasan\File;
// Copy entire directory
File::copyDirectory('/path/to/source/', '/path/to/destination/');
// Copy theme
File::copyDirectory(
ROOT_PATH . 'themes/default/',
ROOT_PATH . 'themes/custom/'
);
// Backup system
class BackupSystem
{
public function backupTemplate($templateName)
{
$source = ROOT_PATH . "templates/{$templateName}/";
$backup = ROOT_PATH . "backups/" . date('Y-m-d_His') . "_{$templateName}/";
if (is_dir($source)) {
File::makeDirectory($backup);
File::copyDirectory($source, $backup);
return "Backup created: {$backup}";
}
return "Source not found";
}
public function duplicateProject($projectName)
{
$source = ROOT_PATH . "projects/{$projectName}/";
$newName = $projectName . '_copy';
$dest = ROOT_PATH . "projects/{$newName}/";
File::copyDirectory($source, $dest);
return "Project duplicated: {$newName}";
}
}
// Theme installer system
class ThemeInstaller
{
public function install($themeName)
{
$source = ROOT_PATH . "downloads/{$themeName}/";
$dest = ROOT_PATH . "themes/{$themeName}/";
if (!is_dir($source)) {
return ['error' => 'Theme package not found'];
}
// Copy theme
File::copyDirectory($source, $dest);
// Remove package
File::removeDirectory($source);
return ['success' => "Theme {$themeName} installed"];
}
}ext()
Get file extension
public static function ext(string $path): stringParameters:
$path- File path or filename
Returns: File extension (lowercase)
Example:
use Kotchasan\File;
// Basic usage
echo File::ext('config.php'); // "php"
echo File::ext('image.JPG'); // "jpg"
echo File::ext('document.pdf'); // "pdf"
echo File::ext('/path/to/file.txt'); // "txt"
echo File::ext('archive.tar.gz'); // "gz"
// Check file type
function isImageFile($filename)
{
$imageExts = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
return in_array(File::ext($filename), $imageExts);
}
echo isImageFile('photo.jpg') ? 'Yes' : 'No'; // "Yes"
echo isImageFile('document.pdf') ? 'Yes' : 'No'; // "No"
// File upload validation
class FileUpload
{
private $allowedExts = ['jpg', 'png', 'pdf', 'doc', 'docx'];
public function validate($filename)
{
$ext = File::ext($filename);
if (!in_array($ext, $this->allowedExts)) {
return [
'valid' => false,
'error' => "File type .{$ext} not allowed"
];
}
return ['valid' => true];
}
public function getFileType($filename)
{
$ext = File::ext($filename);
$types = [
'jpg' => 'image', 'png' => 'image', 'gif' => 'image',
'pdf' => 'document', 'doc' => 'document', 'docx' => 'document',
'mp4' => 'video', 'avi' => 'video',
'mp3' => 'audio', 'wav' => 'audio'
];
return $types[$ext] ?? 'unknown';
}
}
$upload = new FileUpload();
echo $upload->getFileType('photo.jpg'); // "image"
echo $upload->getFileType('report.pdf'); // "document"
// File icon mapping
class FileIcon
{
public static function getIcon($filename)
{
$ext = File::ext($filename);
$icons = [
'php' => '📄', 'js' => '📜', 'css' => '🎨',
'jpg' => '🖼️', 'png' => '🖼️', 'gif' => '🖼️',
'pdf' => '📕', 'doc' => '📘', 'xls' => '📊',
'zip' => '📦', 'rar' => '📦',
'mp4' => '🎬', 'mp3' => '🎵'
];
return $icons[$ext] ?? '📄';
}
}
echo FileIcon::getIcon('photo.jpg'); // "🖼️"
echo FileIcon::getIcon('music.mp3'); // "🎵"listFiles()
List all files in directory and subdirectories
public static function listFiles(
string $dir,
array &$result,
array $filter = []
): voidParameters:
$dir- Directory path (must have trailing/)$result- Array to store results (passed by reference)$filter- Array of file extensions to filter (optional, lowercase)
Returns: void (results stored in $result)
Example:
use Kotchasan\File;
// List all files
$files = [];
File::listFiles('/path/to/directory/', $files);
print_r($files);
// Filter PHP files only
$phpFiles = [];
File::listFiles(ROOT_PATH . 'app/', $phpFiles, ['php']);
foreach ($phpFiles as $file) {
echo $file . "\n";
}
// Find all images
$images = [];
File::listFiles(ROOT_PATH . 'uploads/', $images, ['jpg', 'png', 'gif']);
echo "Found " . count($images) . " images\n";
// File search system
class FileSearch
{
public function findByExtension($dir, $extensions)
{
$files = [];
File::listFiles($dir, $files, $extensions);
return $files;
}
public function findByPattern($dir, $pattern)
{
$allFiles = [];
File::listFiles($dir, $allFiles);
return array_filter($allFiles, function($file) use ($pattern) {
return strpos(basename($file), $pattern) !== false;
});
}
public function getFileStats($dir)
{
$files = [];
File::listFiles($dir, $files);
$stats = [
'total' => count($files),
'size' => 0,
'types' => []
];
foreach ($files as $file) {
$stats['size'] += filesize($file);
$ext = File::ext($file);
$stats['types'][$ext] = ($stats['types'][$ext] ?? 0) + 1;
}
return $stats;
}
}
// Code analyzer
class CodeAnalyzer
{
public function countLines($dir)
{
$phpFiles = [];
File::listFiles($dir, $phpFiles, ['php']);
$totalLines = 0;
foreach ($phpFiles as $file) {
$lines = count(file($file));
$totalLines += $lines;
}
return [
'files' => count($phpFiles),
'lines' => $totalLines,
'average' => round($totalLines / max(count($phpFiles), 1))
];
}
}
// Media library
class MediaLibrary
{
public function getImages($uploadDir)
{
$images = [];
File::listFiles($uploadDir, $images, ['jpg', 'jpeg', 'png', 'gif', 'webp']);
$result = [];
foreach ($images as $path) {
$result[] = [
'path' => $path,
'name' => basename($path),
'size' => filesize($path),
'modified' => filemtime($path)
];
}
return $result;
}
}makeDirectory()
Create directory with permissions validation
public static function makeDirectory(string $dir, int $mode = 0755): boolParameters:
$dir- Directory path to create$mode- Permission mode (default: 0755)
Returns: true = created/writable, false = failed
Example:
use Kotchasan\File;
// Create basic directory
$success = File::makeDirectory('/path/to/newdir/');
if ($success) {
echo "Directory created";
} else {
echo "Failed to create directory";
}
// With custom permissions
File::makeDirectory('/path/to/dir/', 0777); // Full permission
File::makeDirectory('/path/to/dir/', 0755); // Owner rwx, others rx
// Upload system
class UploadManager
{
public function prepareUploadDirectory($userId)
{
$userDir = ROOT_PATH . "uploads/user_{$userId}/";
if (!File::makeDirectory($userDir)) {
return ['error' => 'Cannot create upload directory'];
}
// Create directory structure
File::makeDirectory($userDir . 'images/');
File::makeDirectory($userDir . 'documents/');
File::makeDirectory($userDir . 'videos/');
return ['success' => 'Upload directory ready'];
}
}
// Cache system
class CacheManager
{
private $cacheDir;
public function __construct()
{
$this->cacheDir = ROOT_PATH . 'storage/cache/';
File::makeDirectory($this->cacheDir);
}
public function write($key, $data, $ttl = 3600)
{
$file = $this->cacheDir . md5($key) . '.cache';
$cacheData = [
'expires' => time() + $ttl,
'data' => $data
];
file_put_contents($file, serialize($cacheData));
}
public function read($key)
{
$file = $this->cacheDir . md5($key) . '.cache';
if (!file_exists($file)) {
return null;
}
$cacheData = unserialize(file_get_contents($file));
if ($cacheData['expires'] < time()) {
unlink($file);
return null;
}
return $cacheData['data'];
}
}
// Log system
class Logger
{
private $logDir;
public function __construct()
{
$this->logDir = ROOT_PATH . 'storage/logs/';
if (!File::makeDirectory($this->logDir)) {
throw new \Exception('Cannot create log directory');
}
}
public function log($level, $message)
{
$date = date('Y-m-d');
$logFile = $this->logDir . "{$level}_{$date}.log";
$entry = sprintf(
"[%s] [%s] %s\n",
date('Y-m-d H:i:s'),
strtoupper($level),
$message
);
file_put_contents($logFile, $entry, FILE_APPEND);
}
}removeDirectory()
Remove directory and all contents recursively
public static function removeDirectory(string $dir, bool $removeSelf = true): voidParameters:
$dir- Directory path to remove (must have trailing/)$removeSelf-true= remove directory itself,false= remove only contents
Returns: void
Example:
use Kotchasan\File;
// Remove entire directory
File::removeDirectory('/path/to/directory/');
// Remove only contents (keep directory)
File::removeDirectory('/path/to/cache/', false);
// Cleanup system
class CleanupManager
{
public function clearCache()
{
$cacheDir = ROOT_PATH . 'storage/cache/';
// Clear all cache files but keep directory
File::removeDirectory($cacheDir, false);
return "Cache cleared";
}
public function clearOldLogs($daysOld = 30)
{
$logDir = ROOT_PATH . 'storage/logs/';
$files = [];
File::listFiles($logDir, $files, ['log']);
$cutoff = time() - ($daysOld * 86400);
$removed = 0;
foreach ($files as $file) {
if (filemtime($file) < $cutoff) {
unlink($file);
$removed++;
}
}
return "Removed {$removed} old log files";
}
public function clearTempFiles()
{
$tempDir = ROOT_PATH . 'storage/temp/';
File::removeDirectory($tempDir, false);
return "Temp files cleared";
}
}
// Uninstaller
class ModuleUninstaller
{
public function uninstall($moduleName)
{
$moduleDir = ROOT_PATH . "modules/{$moduleName}/";
if (!is_dir($moduleDir)) {
return ['error' => 'Module not found'];
}
// Remove entire module directory
File::removeDirectory($moduleDir);
return ['success' => "Module {$moduleName} uninstalled"];
}
public function reset($moduleName)
{
$dataDir = ROOT_PATH . "modules/{$moduleName}/data/";
// Remove data but keep structure
File::removeDirectory($dataDir, false);
return ['success' => "Module {$moduleName} reset"];
}
}
// Backup rotation
class BackupRotation
{
private $backupDir;
private $maxBackups = 5;
public function __construct($backupDir)
{
$this->backupDir = $backupDir;
File::makeDirectory($backupDir);
}
public function rotate()
{
$backups = [];
File::listFiles($this->backupDir, $backups);
// Sort by time (oldest first)
usort($backups, function($a, $b) {
return filemtime($a) - filemtime($b);
});
// Remove old backups exceeding limit
$toRemove = count($backups) - $this->maxBackups;
if ($toRemove > 0) {
for ($i = 0; $i < $toRemove; $i++) {
if (is_dir($backups[$i])) {
File::removeDirectory($backups[$i]);
} else {
unlink($backups[$i]);
}
}
}
return "Kept latest {$this->maxBackups} backups";
}
}Real-World Examples
1. Asset Compiler System
use Kotchasan\File;
class AssetCompiler
{
public function compileAssets()
{
$sourceDir = ROOT_PATH . 'resources/';
$buildDir = ROOT_PATH . 'public/assets/';
// Create build directory
File::makeDirectory($buildDir);
// Clear previous build
File::removeDirectory($buildDir, false);
// Find CSS files
$cssFiles = [];
File::listFiles($sourceDir . 'css/', $cssFiles, ['css']);
// Find JS files
$jsFiles = [];
File::listFiles($sourceDir . 'js/', $jsFiles, ['js']);
// Compile CSS
$this->compileCss($cssFiles, $buildDir . 'app.css');
// Compile JS
$this->compileJs($jsFiles, $buildDir . 'app.js');
// Copy images
File::copyDirectory(
$sourceDir . 'images/',
$buildDir . 'images/'
);
return "Assets compiled successfully";
}
private function compileCss($files, $output)
{
$combined = '';
foreach ($files as $file) {
$combined .= file_get_contents($file) . "\n";
}
file_put_contents($output, $combined);
}
private function compileJs($files, $output)
{
$combined = '';
foreach ($files as $file) {
$combined .= file_get_contents($file) . ";\n";
}
file_put_contents($output, $combined);
}
}2. File Manager System
class FileManager
{
private $baseDir;
public function __construct($baseDir)
{
$this->baseDir = rtrim($baseDir, '/') . '/';
File::makeDirectory($this->baseDir);
}
public function listDirectory($path = '')
{
$fullPath = $this->baseDir . $path;
if (!is_dir($fullPath)) {
return ['error' => 'Directory not found'];
}
$items = [];
$handle = opendir($fullPath);
while (false !== ($item = readdir($handle))) {
if ($item === '.' || $item === '..') {
continue;
}
$itemPath = $fullPath . $item;
$isDir = is_dir($itemPath);
$items[] = [
'name' => $item,
'type' => $isDir ? 'directory' : 'file',
'size' => $isDir ? null : filesize($itemPath),
'extension' => $isDir ? null : File::ext($item),
'modified' => filemtime($itemPath)
];
}
closedir($handle);
return $items;
}
public function createDirectory($path)
{
$fullPath = $this->baseDir . $path . '/';
if (File::makeDirectory($fullPath)) {
return ['success' => 'Directory created'];
}
return ['error' => 'Cannot create directory'];
}
public function deleteDirectory($path)
{
$fullPath = $this->baseDir . $path . '/';
File::removeDirectory($fullPath);
return ['success' => 'Directory deleted'];
}
public function copyDirectory($source, $dest)
{
$sourcePath = $this->baseDir . $source . '/';
$destPath = $this->baseDir . $dest . '/';
File::makeDirectory($destPath);
File::copyDirectory($sourcePath, $destPath);
return ['success' => 'Directory copied'];
}
}Best Practices
1. Use Trailing Slash
// ✅ Good - has trailing slash
File::copyDirectory('/path/to/source/', '/path/to/dest/');
File::listFiles('/path/to/dir/', $files);
// ❌ Bad - no trailing slash (may cause errors)
File::copyDirectory('/path/to/source', '/path/to/dest');2. Check Permissions Before Use
// ✅ Good
if (File::makeDirectory($dir)) {
// Proceed
} else {
// Handle error
}
// ❌ Bad
File::makeDirectory($dir); // No return value check3. Be Careful When Deleting Directories
// ✅ Good - with confirmation
function deleteUserData($userId)
{
$confirm = readline("Delete all data for user {$userId}? (yes/no): ");
if ($confirm === 'yes') {
File::removeDirectory("/data/users/{$userId}/");
}
}
// ❌ Bad - deletes immediately without confirmation
File::removeDirectory($dir); // Dangerous!4. Filter File Extensions
// ✅ Good - filter only what you need
$images = [];
File::listFiles($dir, $images, ['jpg', 'png']);
// ❌ Bad - gets all files
$all = [];
File::listFiles($dir, $all); // May include unwanted filesImportant Considerations
[!WARNING]
removeDirectory(): Permanently deletes files, cannot be recovered. Use with caution![!IMPORTANT]
Permissions: Ensure proper read/write/delete permissions in operating system[!NOTE]
Trailing Slash: Methods accepting directory paths require trailing/[!TIP]
Error Handling: Methods use@to suppress warnings, check return values
Related Classes
- [Files] - File upload and validation
- Image - Image processing
Summary
File class has 5 main methods:
- copyDirectory() - Copy entire directory
- ext() - Get file extension
- listFiles() - List files with filtering
- makeDirectory() - Create directory with permissions
- removeDirectory() - Remove directory and contents
Perfect for:
- File management systems
- Backup/Restore systems
- Asset compilation
- Cache management
- Module/Plugin systems