# Byte Value Object The `Byte` value object provides a type-safe way to work with byte sizes in your application. It offers convenient conversions, arithmetic operations, and human-readable formatting for file sizes, memory usage, and other byte-based measurements. ## Basic Usage ### Creating Byte Instances ```php use App\Framework\Core\ValueObjects\Byte; use App\Framework\Core\ValueObjects\ByteUnit; // From raw bytes $size = Byte::fromBytes(1048576); // 1 MB // From specific units $fileSize = Byte::fromMegabytes(5.5); $memoryLimit = Byte::fromGigabytes(2); $smallFile = Byte::fromKilobytes(256); // From human-readable strings $uploadLimit = Byte::parse('10MB'); $cacheSize = Byte::parse('500 KB'); $logSize = Byte::parse('1.5GB'); // Using enum for flexibility $customSize = Byte::fromUnit(100, ByteUnit::MEGABYTE); ``` ### Converting Between Units ```php $size = Byte::fromMegabytes(5.5); echo $size->toBytes(); // 5767168 echo $size->toKilobytes(); // 5632.0 echo $size->toMegabytes(); // 5.5 echo $size->toGigabytes(); // 0.01 // Custom precision echo $size->toGigabytes(4); // 0.0054 // Using enum for dynamic conversion $unit = ByteUnit::KILOBYTE; echo $size->toUnit($unit); // 5632.0 ``` ### Human-Readable Formatting ```php $size = Byte::fromBytes(1536000); echo $size->toHumanReadable(); // "1.46 MB" echo $size->toHumanReadable(0); // "1 MB" echo (string) $size; // "1.46 MB" (same as toHumanReadable()) // Get the best unit for display $unit = $size->getBestUnit(); // ByteUnit::MEGABYTE echo $unit->value; // "MB" echo $unit->getName(); // "Megabyte" ``` ## Arithmetic Operations ```php $file1 = Byte::fromMegabytes(5); $file2 = Byte::fromMegabytes(3); // Addition $total = $file1->add($file2); // 8 MB // Subtraction $difference = $file1->subtract($file2); // 2 MB // Multiplication $doubled = $file1->multiply(2); // 10 MB // Division $half = $file1->divide(2); // 2.5 MB // Percentage calculation $percentage = $file1->percentOf($total); // 62.5 ``` ## Comparisons ```php $file1 = Byte::fromMegabytes(5); $file2 = Byte::fromMegabytes(3); $limit = Byte::fromMegabytes(10); // Equality if ($file1->equals($file2)) { echo "Files are the same size"; } // Size comparisons if ($file1->greaterThan($file2)) { echo "File 1 is larger"; } if ($file1->lessThan($limit)) { echo "File is under the limit"; } // Utility checks if ($file1->isEmpty()) { echo "File is empty"; } ``` ## Framework Integration Examples ### File Upload Validation ```php class FileUploadMiddleware { public function validate(UploadedFile $file): void { $maxSize = Byte::parse($_ENV['MAX_UPLOAD_SIZE'] ?? '10MB'); $fileSize = Byte::fromBytes($file->getSize()); if ($fileSize->greaterThan($maxSize)) { throw new ValidationException( "File size {$fileSize} exceeds limit of {$maxSize}" ); } } } ``` ### Memory Usage Monitoring ```php class PerformanceMonitor { public function checkMemoryUsage(): array { $current = Byte::fromBytes(memory_get_usage(true)); $peak = Byte::fromBytes(memory_get_peak_usage(true)); $limit = Byte::parse(ini_get('memory_limit')); return [ 'current' => $current->toHumanReadable(), 'peak' => $peak->toHumanReadable(), 'limit' => $limit->toHumanReadable(), 'usage_percentage' => $current->percentOf($limit), ]; } } ``` ### Database Entity ```php use App\Framework\Database\Attributes\Column; use App\Framework\Database\Attributes\Entity; #[Entity(tableName: 'files')] final readonly class File { public function __construct( #[Column(name: 'id', primary: true)] public int $id, #[Column(name: 'filename')] public string $filename, #[Column(name: 'file_size')] public int $fileSizeBytes, ) {} public function getFileSize(): Byte { return Byte::fromBytes($this->fileSizeBytes); } public function isLargeFile(): bool { return $this->getFileSize()->greaterThan(Byte::fromMegabytes(50)); } } ``` ### Cache Size Management ```php class CacheManager { public function cleanupIfNeeded(): void { $cacheSize = $this->getCurrentCacheSize(); $maxSize = Byte::parse($_ENV['CACHE_MAX_SIZE'] ?? '1GB'); if ($cacheSize->greaterThan($maxSize)) { $this->clearOldEntries(); $newSize = $this->getCurrentCacheSize(); $freed = $cacheSize->subtract($newSize); $this->logger->info("Cache cleanup freed {$freed}"); } } private function getCurrentCacheSize(): Byte { $totalBytes = 0; foreach ($this->getCacheFiles() as $file) { $totalBytes += filesize($file); } return Byte::fromBytes($totalBytes); } } ``` ## ByteUnit Enum The `ByteUnit` enum provides type-safe unit definitions: ```php // Available units ByteUnit::BYTE // 'B' ByteUnit::KILOBYTE // 'KB' ByteUnit::MEGABYTE // 'MB' ByteUnit::GIGABYTE // 'GB' ByteUnit::TERABYTE // 'TB' // Get multiplier $multiplier = ByteUnit::MEGABYTE->getMultiplier(); // 1048576 // Get human name $name = ByteUnit::GIGABYTE->getName(); // "Gigabyte" // Find best unit for a size $unit = ByteUnit::bestUnitFor(1048576); // ByteUnit::MEGABYTE // Parse from string $unit = ByteUnit::fromString('MB'); // ByteUnit::MEGABYTE $unit = ByteUnit::fromString('megabytes'); // ByteUnit::MEGABYTE ``` ## Constants ```php // Common sizes $empty = Byte::zero(); // 0 B $kb = Byte::oneKilobyte(); // 1 KB $mb = Byte::oneMegabyte(); // 1 MB $gb = Byte::oneGigabyte(); // 1 GB ``` ## Configuration Examples ### Environment Variables ```bash # .env file MAX_UPLOAD_SIZE=10MB CACHE_MAX_SIZE=1GB LOG_MAX_SIZE=100MB MEMORY_LIMIT_WARNING=512MB ``` ### Application Usage ```php // Configuration class class AppConfig { public static function getMaxUploadSize(): Byte { return Byte::parse($_ENV['MAX_UPLOAD_SIZE'] ?? '5MB'); } public static function getCacheLimit(): Byte { return Byte::parse($_ENV['CACHE_MAX_SIZE'] ?? '500MB'); } } // Usage in controllers class FileController { public function upload(Request $request): Response { $maxSize = AppConfig::getMaxUploadSize(); foreach ($request->files as $file) { $fileSize = Byte::fromBytes($file->getSize()); if ($fileSize->greaterThan($maxSize)) { return new JsonResponse([ 'error' => "File {$file->getName()} ({$fileSize}) exceeds maximum size of {$maxSize}" ], 413); } } // Process upload... } } ``` ## Error Handling ```php try { // Invalid format $size = Byte::parse('invalid'); } catch (InvalidArgumentException $e) { echo $e->getMessage(); // "Invalid byte format: invalid" } try { // Negative bytes $size = Byte::fromBytes(-100); } catch (InvalidArgumentException $e) { echo $e->getMessage(); // "Bytes cannot be negative" } try { // Subtraction resulting in negative $result = Byte::fromBytes(100)->subtract(Byte::fromBytes(200)); } catch (InvalidArgumentException $e) { echo $e->getMessage(); // "Subtraction would result in negative bytes" } ``` ## Best Practices 1. **Use in Configuration**: Store all size limits as `Byte` objects for type safety 2. **Database Storage**: Store raw bytes as integers, convert to `Byte` objects in getters 3. **Validation**: Use `Byte` objects for all size-related validation logic 4. **Logging**: Use `toHumanReadable()` for user-friendly log messages 5. **APIs**: Accept string formats and parse them into `Byte` objects 6. **Performance**: Create `Byte` objects lazily when needed, store raw bytes when possible