upload_path = UPLOAD_PATH; $this->allowed_types = ALLOWED_IMAGE_TYPES; $this->max_size = MAX_IMAGE_SIZE; if (!file_exists($this->upload_path)) { mkdir($this->upload_path, 0755, true); } } public function upload($file, $optimize = true) { if (!isset($file['tmp_name']) || !is_uploaded_file($file['tmp_name'])) { throw new Exception('No file uploaded'); } // Validate file $this->validateFile($file); // Generate unique filename $extension = pathinfo($file['name'], PATHINFO_EXTENSION); $filename = uniqid() . '_' . time() . '.' . $extension; $filepath = $this->upload_path . '/' . $filename; // Move and optimize if (move_uploaded_file($file['tmp_name'], $filepath)) { if ($optimize) { $this->optimizeImage($filepath); } return $filename; } throw new Exception('Failed to move uploaded file'); } private function validateFile($file) { // Check file size if ($file['size'] > $this->max_size) { throw new Exception('File size exceeds limit'); } // Check file type $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($finfo, $file['tmp_name']); finfo_close($finfo); if (!in_array($mime_type, $this->allowed_types)) { throw new Exception('Invalid file type'); } } private function optimizeImage($filepath) { $image = null; $mime = mime_content_type($filepath); switch ($mime) { case 'image/jpeg': $image = imagecreatefromjpeg($filepath); imagejpeg($image, $filepath, 85); // 85% quality break; case 'image/png': $image = imagecreatefrompng($filepath); imagepng($image, $filepath, 8); // Compression level 8 break; case 'image/webp': $image = imagecreatefromwebp($filepath); imagewebp($image, $filepath, 85); break; } if ($image) { imagedestroy($image); } } public function createThumbnail($filename, $width = 200, $height = 200) { $source_path = $this->upload_path . '/' . $filename; $thumb_path = $this->upload_path . '/thumbnails/' . $filename; if (!file_exists(dirname($thumb_path))) { mkdir(dirname($thumb_path), 0755, true); } $source_image = imagecreatefromstring(file_get_contents($source_path)); $source_width = imagesx($source_image); $source_height = imagesy($source_image); $thumb = imagecreatetruecolor($width, $height); imagecopyresampled($thumb, $source_image, 0, 0, 0, 0, $width, $height, $source_width, $source_height); $mime = mime_content_type($source_path); switch ($mime) { case 'image/jpeg': imagejpeg($thumb, $thumb_path, 85); break; case 'image/png': imagepng($thumb, $thumb_path, 8); break; case 'image/webp': imagewebp($thumb, $thumb_path, 85); break; } imagedestroy($source_image); imagedestroy($thumb); return 'thumbnails/' . $filename; } }