Kotchasan Framework Documentation
Files Class - Uploaded Files Collection
Files Class - Uploaded Files Collection
The Files class is an Iterator for managing collections of uploaded files, used with UploadedFile within the Kotchasan Framework.
Namespace
Kotchasan\FilesOverview
The Files class implements the \Iterator interface, allowing it to be used in foreach loops.
API Reference
__construct()
Create a new instance of the file collection
public function __construct()Example:
use Kotchasan\Files;
// Create new file collection
$files = new Files();add()
Add a file to the collection
public function add($name, $path, $originalName, $mimeType = null, $size = null, $error = null)Parameters:
$name- Input name$path- Uploaded file path$originalName- Original filename$mimeType- MIME Type (optional)$size- File size (optional)$error- Error code UPLOAD_ERR_XXX (optional)
Returns: void
Example:
use Kotchasan\Files;
$files = new Files();
// Add image file
$files->add('profile_image', '/tmp/upload123', 'avatar.jpg', 'image/jpeg', 1024000, UPLOAD_ERR_OK);
// Add document file
$files->add('document', '/tmp/upload124', 'resume.pdf', 'application/pdf', 2048000, UPLOAD_ERR_OK);
// Add file with error
$files->add('large_file', '/tmp/upload125', 'video.mp4', 'video/mp4', 50000000, UPLOAD_ERR_FORM_SIZE);
// Use with $_FILES data
foreach ($_FILES as $inputName => $fileData) {
if (is_array($fileData['name'])) {
// Multiple files
for ($i = 0; $i < count($fileData['name']); $i++) {
$files->add(
$inputName,
$fileData['tmp_name'][$i],
$fileData['name'][$i],
$fileData['type'][$i],
$fileData['size'][$i],
$fileData['error'][$i]
);
}
} else {
// Single file
$files->add(
$inputName,
$fileData['tmp_name'],
$fileData['name'],
$fileData['type'],
$fileData['size'],
$fileData['error']
);
}
}get()
Get file by specified key
public function get($key)Parameters:
$key(string|int) - The requested key
Returns: \Kotchasan\Http\UploadedFile|null - UploadedFile object or null if not found
Example:
use Kotchasan\Files;
$files = new Files();
$files->add('profile', '/tmp/upload123', 'avatar.jpg', 'image/jpeg', 1024000, UPLOAD_ERR_OK);
$files->add('document', '/tmp/upload124', 'resume.pdf', 'application/pdf', 2048000, UPLOAD_ERR_OK);
// Get profile file
$profileFile = $files->get('profile');
if ($profileFile) {
echo "Profile: " . $profileFile->getClientFilename();
echo "Size: " . $profileFile->getSize() . " bytes";
}
// Get document file
$documentFile = $files->get('document');
if ($documentFile) {
echo "Document: " . $documentFile->getClientFilename();
echo "Type: " . $documentFile->getClientMediaType();
}
// Check for non-existent file
$missingFile = $files->get('nonexistent');
if ($missingFile === null) {
echo "File not found";
}Iterator Methods
The Files class implements the Iterator interface to be usable in foreach loops
public function rewind() // Reset to first
public function valid() // Check if data exists (returns bool)
public function current() // Get current file (returns UploadedFile)
public function key() // Get current key (returns string)
public function next() // Move to next fileExample:
use Kotchasan\Files;
use Kotchasan\File;
$files = new Files();
$files->add('image1', '/tmp/upload1', 'photo1.jpg', 'image/jpeg', 1024000, UPLOAD_ERR_OK);
$files->add('image2', '/tmp/upload2', 'photo2.png', 'image/png', 2048000, UPLOAD_ERR_OK);
$files->add('document', '/tmp/upload3', 'doc.pdf', 'application/pdf', 3072000, UPLOAD_ERR_OK);
// Loop through all files
foreach ($files as $inputName => $uploadedFile) {
echo "Input: {$inputName}\n";
echo "Filename: " . $uploadedFile->getClientFilename() . "\n";
echo "Size: " . $uploadedFile->getSize() . " bytes\n";
echo "Type: " . $uploadedFile->getClientMediaType() . "\n";
echo "Status: " . ($uploadedFile->getError() === UPLOAD_ERR_OK ? 'Success' : 'Error') . "\n";
echo "---\n";
}
// Process all files example
function processAllFiles($files) {
$results = [];
foreach ($files as $inputName => $uploadedFile) {
$result = [
'input_name' => $inputName,
'original_name' => $uploadedFile->getClientFilename(),
'size' => $uploadedFile->getSize(),
'type' => $uploadedFile->getClientMediaType(),
'error' => $uploadedFile->getError(),
'processed' => false,
'message' => ''
];
if ($uploadedFile->getError() === UPLOAD_ERR_OK) {
// Process file
$extension = File::ext($uploadedFile->getClientFilename());
$allowedTypes = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx'];
if (in_array($extension, $allowedTypes)) {
$result['processed'] = true;
$result['message'] = 'File processed successfully';
} else {
$result['message'] = 'File type not allowed';
}
} else {
$result['message'] = 'Upload error: ' . $uploadedFile->getError();
}
$results[] = $result;
}
return $results;
}
// Filter files by type example
function filterFilesByType($files, $allowedTypes) {
$filtered = new Files();
foreach ($files as $inputName => $uploadedFile) {
$extension = File::ext($uploadedFile->getClientFilename());
if (in_array($extension, $allowedTypes)) {
$filtered->add(
$inputName,
$uploadedFile->getStream()->getMetadata('uri'),
$uploadedFile->getClientFilename(),
$uploadedFile->getClientMediaType(),
$uploadedFile->getSize(),
$uploadedFile->getError()
);
}
}
return $filtered;
}
// Generate upload report example
function generateUploadReport($files) {
$report = [
'total_files' => 0,
'successful_uploads' => 0,
'failed_uploads' => 0,
'total_size' => 0,
'file_types' => [],
'errors' => []
];
foreach ($files as $inputName => $uploadedFile) {
$report['total_files']++;
if ($uploadedFile->getError() === UPLOAD_ERR_OK) {
$report['successful_uploads']++;
$report['total_size'] += $uploadedFile->getSize();
$extension = File::ext($uploadedFile->getClientFilename());
$report['file_types'][$extension] = ($report['file_types'][$extension] ?? 0) + 1;
} else {
$report['failed_uploads']++;
$report['errors'][] = [
'input_name' => $inputName,
'filename' => $uploadedFile->getClientFilename(),
'error_code' => $uploadedFile->getError()
];
}
}
return $report;
}Real-World Examples
1. Image Upload Manager System
use Kotchasan\Files;
use Kotchasan\File;
use Kotchasan\Image;
class ImageUploadManager
{
public static function processImageUploads($files, $uploadDir)
{
$results = [];
foreach ($files as $inputName => $uploadedFile) {
if ($uploadedFile->getError() !== UPLOAD_ERR_OK) {
$results[] = [
'input_name' => $inputName,
'success' => false,
'message' => 'Upload error: ' . $uploadedFile->getError()
];
continue;
}
$extension = File::ext($uploadedFile->getClientFilename());
if (!in_array($extension, ['jpg', 'jpeg', 'png', 'gif'])) {
$results[] = [
'input_name' => $inputName,
'success' => false,
'message' => 'File type is not an image'
];
continue;
}
// Generate new filename
$newFilename = uniqid() . '.' . $extension;
$targetPath = $uploadDir . $newFilename;
// Move file
$uploadedFile->moveTo($targetPath);
// Create thumbnail
$thumbnailPath = $uploadDir . 'thumbs/' . $newFilename;
File::makeDirectory(dirname($thumbnailPath));
Image::crop($targetPath, $thumbnailPath, 200, 200);
$results[] = [
'input_name' => $inputName,
'success' => true,
'original_name' => $uploadedFile->getClientFilename(),
'saved_name' => $newFilename,
'path' => $targetPath,
'thumbnail' => $thumbnailPath,
'size' => $uploadedFile->getSize()
];
}
return $results;
}
}2. Document Upload Manager System
class DocumentUploadManager
{
public static function processDocumentUploads($files, $uploadDir, $userId)
{
$userDir = $uploadDir . "user_{$userId}/";
File::makeDirectory($userDir);
$results = [];
foreach ($files as $inputName => $uploadedFile) {
if ($uploadedFile->getError() !== UPLOAD_ERR_OK) {
$results[] = [
'input_name' => $inputName,
'success' => false,
'message' => 'Upload error'
];
continue;
}
$extension = File::ext($uploadedFile->getClientFilename());
$allowedTypes = ['pdf', 'doc', 'docx', 'txt', 'xls', 'xlsx'];
if (!in_array($extension, $allowedTypes)) {
$results[] = [
'input_name' => $inputName,
'success' => false,
'message' => 'Document type not allowed'
];
continue;
}
// Check file size (10MB max)
if ($uploadedFile->getSize() > 10 * 1024 * 1024) {
$results[] = [
'input_name' => $inputName,
'success' => false,
'message' => 'File size exceeds limit (max 10MB)'
];
continue;
}
$safeFilename = date('Y-m-d_H-i-s') . '_' . $uploadedFile->getClientFilename();
$targetPath = $userDir . $safeFilename;
$uploadedFile->moveTo($targetPath);
$results[] = [
'input_name' => $inputName,
'success' => true,
'original_name' => $uploadedFile->getClientFilename(),
'saved_name' => $safeFilename,
'path' => $targetPath,
'size' => $uploadedFile->getSize(),
'type' => $uploadedFile->getClientMediaType()
];
}
return $results;
}
}3. Multi-File Upload System
class MultiFileUploader
{
public function handleUpload()
{
$files = new Files();
// Process $_FILES data
foreach ($_FILES as $inputName => $fileData) {
if (is_array($fileData['name'])) {
// Multiple files
for ($i = 0; $i < count($fileData['name']); $i++) {
if (!empty($fileData['name'][$i])) {
$files->add(
$inputName . '[' . $i . ']',
$fileData['tmp_name'][$i],
$fileData['name'][$i],
$fileData['type'][$i],
$fileData['size'][$i],
$fileData['error'][$i]
);
}
}
} else {
// Single file
if (!empty($fileData['name'])) {
$files->add(
$inputName,
$fileData['tmp_name'],
$fileData['name'],
$fileData['type'],
$fileData['size'],
$fileData['error']
);
}
}
}
return $this->processFiles($files);
}
private function processFiles($files)
{
$uploadDir = ROOT_PATH . 'datas/uploads/' . date('Y/m/d') . '/';
File::makeDirectory($uploadDir);
$results = [
'uploaded' => [],
'failed' => [],
'summary' => [
'total' => 0,
'success' => 0,
'failed' => 0
]
];
foreach ($files as $inputName => $uploadedFile) {
$results['summary']['total']++;
$result = $this->processFile($uploadedFile, $uploadDir);
$result['input_name'] = $inputName;
if ($result['success']) {
$results['uploaded'][] = $result;
$results['summary']['success']++;
} else {
$results['failed'][] = $result;
$results['summary']['failed']++;
}
}
return $results;
}
private function processFile($uploadedFile, $uploadDir)
{
if ($uploadedFile->getError() !== UPLOAD_ERR_OK) {
return [
'success' => false,
'message' => $this->getUploadErrorMessage($uploadedFile->getError()),
'original_name' => $uploadedFile->getClientFilename()
];
}
$extension = File::ext($uploadedFile->getClientFilename());
$allowedTypes = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx'];
if (!in_array($extension, $allowedTypes)) {
return [
'success' => false,
'message' => 'File type not allowed',
'original_name' => $uploadedFile->getClientFilename()
];
}
$filename = uniqid() . '_' . $uploadedFile->getClientFilename();
$targetPath = $uploadDir . $filename;
try {
$uploadedFile->moveTo($targetPath);
return [
'success' => true,
'message' => 'Upload successful',
'original_name' => $uploadedFile->getClientFilename(),
'saved_name' => $filename,
'path' => $targetPath,
'size' => $uploadedFile->getSize(),
'url' => str_replace(ROOT_PATH, WEB_URL, $targetPath)
];
} catch (Exception $e) {
return [
'success' => false,
'message' => 'Cannot save file: ' . $e->getMessage(),
'original_name' => $uploadedFile->getClientFilename()
];
}
}
private function getUploadErrorMessage($errorCode)
{
$messages = [
UPLOAD_ERR_INI_SIZE => 'File size exceeds system limit',
UPLOAD_ERR_FORM_SIZE => 'File size exceeds form limit',
UPLOAD_ERR_PARTIAL => 'File was partially uploaded',
UPLOAD_ERR_NO_FILE => 'No file was uploaded',
UPLOAD_ERR_NO_TMP_DIR => 'Temporary directory not found',
UPLOAD_ERR_CANT_WRITE => 'Cannot write file to disk',
UPLOAD_ERR_EXTENSION => 'Upload stopped by extension'
];
return $messages[$errorCode] ?? 'Unknown error';
}
}
// Use in controller
class UploadController extends \Kotchasan\Controller
{
public function upload()
{
if ($this->request->getMethod() === 'POST') {
$uploader = new MultiFileUploader();
$results = $uploader->handleUpload();
// Return results as JSON
header('Content-Type: application/json');
echo json_encode($results);
} else {
// Show upload form
include ROOT_PATH . 'modules/upload/views/form.php';
}
}
}Usage Notes
- Iterator Pattern: Can be used directly in foreach loops
- UploadedFile: Works with PSR-7 UploadedFile interface
- Memory Efficient: Stores only references, doesn't load entire files into memory
- Flexible: Supports both single and multiple file uploads
Related Classes
- [File] - File and directory management
- Image - Image processing
- UploadedFile - PSR-7 UploadedFile
Summary
Files class has 6 main methods:
- __construct() - Create file collection
- add() - Add file to collection
- get() - Get file by key
- rewind() - Reset iterator
- valid() - Check if data exists
- current(), key(), next() - Iterator methods
Perfect for:
- Image upload systems
- Document upload systems
- Multi-file upload systems
- User file management systems