{"id":18895177,"url":"https://github.com/farisc0de/phpfileuploading","last_synced_at":"2026-01-24T01:02:32.072Z","repository":{"id":38051572,"uuid":"499536682","full_name":"farisc0de/PhpFileUploading","owner":"farisc0de","description":"PHP Library to help you build your own file sharing website.","archived":false,"fork":false,"pushed_at":"2024-02-17T14:38:49.000Z","size":128,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-08T08:46:50.832Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/farisc0de.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-03T14:13:06.000Z","updated_at":"2023-05-19T09:25:14.000Z","dependencies_parsed_at":"2024-11-08T08:39:47.686Z","dependency_job_id":null,"html_url":"https://github.com/farisc0de/PhpFileUploading","commit_stats":{"total_commits":11,"total_committers":3,"mean_commits":"3.6666666666666665","dds":0.5454545454545454,"last_synced_commit":"e3391fdb75b1e32326d9f919492fe3b2838f75a4"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farisc0de%2FPhpFileUploading","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farisc0de%2FPhpFileUploading/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farisc0de%2FPhpFileUploading/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farisc0de%2FPhpFileUploading/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/farisc0de","download_url":"https://codeload.github.com/farisc0de/PhpFileUploading/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231959611,"owners_count":18452112,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T08:26:56.299Z","updated_at":"2026-01-24T01:02:32.058Z","avatar_url":"https://github.com/farisc0de.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PhpFileUploading\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![PHP Version](https://img.shields.io/badge/PHP-8.1%2B-blue.svg)](https://php.net)\n\nProduction-ready PHP library for secure file uploads with validation, virus scanning, rate limiting, and cloud storage support.\n\n## Features\n\n- **Security First**: MIME type validation, extension filtering, forbidden filename blocking, path traversal prevention\n- **Validation System**: Chainable validators with detailed result objects\n- **Rate Limiting**: Prevent abuse with configurable rate limiters (in-memory or file-based)\n- **Virus Scanning**: ClamAV integration for malware detection\n- **Storage Abstraction**: Local storage with Flysystem-compatible interface for cloud providers\n- **Event System**: Hook into upload lifecycle with event listeners\n- **Image Processing**: Resize, compress, watermark, and convert images\n- **Logging**: PSR-3 compatible logging interface\n- **Multi-File Upload**: Handle single and multiple file uploads\n\n## Requirements\n\n- PHP 8.1 or higher\n- `fileinfo` extension\n- `json` extension\n- `gd` extension (for image processing)\n\n## Installation\n\n```bash\ncomposer require farisc0de/phpfileuploading\n```\n\n## Quick Start\n\n### Basic Upload\n\n```php\n\u003c?php\n\nuse Farisc0de\\PhpFileUploading\\Upload;\nuse Farisc0de\\PhpFileUploading\\File;\nuse Farisc0de\\PhpFileUploading\\Utility;\n\n$upload = new Upload(new Utility());\n\n$upload-\u003esetUploadFolder([\n    'folder_name' =\u003e 'uploads',\n    'folder_path' =\u003e realpath('uploads')\n]);\n\n$upload-\u003eenableProtection();\n\nif ($_SERVER['REQUEST_METHOD'] === 'POST') {\n    $file = new File($_FILES['file'], new Utility());\n    $upload-\u003esetUpload($file);\n\n    if ($upload-\u003echeckIfNotEmpty() \u0026\u0026 \n        $upload-\u003echeckExtension() \u0026\u0026 \n        $upload-\u003echeckMime() \u0026\u0026 \n        $upload-\u003echeckSize()) {\n        \n        $upload-\u003ehashName(); // Generate secure filename\n        $upload-\u003eupload();\n        \n        echo \"File uploaded successfully!\";\n    }\n}\n```\n\n### Using the Validation Chain\n\n```php\n\u003c?php\n\nuse Farisc0de\\PhpFileUploading\\File;\nuse Farisc0de\\PhpFileUploading\\Utility;\nuse Farisc0de\\PhpFileUploading\\Validation\\ValidationChain;\nuse Farisc0de\\PhpFileUploading\\Validation\\Validators\\ExtensionValidator;\nuse Farisc0de\\PhpFileUploading\\Validation\\Validators\\MimeTypeValidator;\nuse Farisc0de\\PhpFileUploading\\Validation\\Validators\\SizeValidator;\nuse Farisc0de\\PhpFileUploading\\Validation\\Validators\\FilenameValidator;\n\n$file = new File($_FILES['file'], new Utility());\n\n$validator = new ValidationChain();\n$validator\n    -\u003eaddValidator(new ExtensionValidator(['jpg', 'png', 'gif', 'pdf']))\n    -\u003eaddValidator(new MimeTypeValidator([\n        'image/jpeg', 'image/png', 'image/gif', 'application/pdf'\n    ]))\n    -\u003eaddValidator(new SizeValidator(null, '10 MB'))\n    -\u003eaddValidator(new FilenameValidator(['shell.php', 'backdoor.php']));\n\n$result = $validator-\u003evalidate($file);\n\nif ($result-\u003eisValid()) {\n    // Proceed with upload\n} else {\n    // Handle errors\n    foreach ($result-\u003egetErrors() as $error) {\n        echo $error-\u003egetMessage() . \"\\n\";\n    }\n}\n```\n\n### Rate Limiting\n\n```php\n\u003c?php\n\nuse Farisc0de\\PhpFileUploading\\RateLimiting\\FileRateLimiter;\n\n// Allow 10 uploads per minute per IP\n$limiter = new FileRateLimiter('/path/to/rate-limit-storage', 10, 60);\n\n$clientIp = $_SERVER['REMOTE_ADDR'];\n$result = $limiter-\u003echeck($clientIp);\n\nif (!$result-\u003eisAllowed()) {\n    http_response_code(429);\n    header('Retry-After: ' . $result-\u003egetRetryAfter());\n    die('Rate limit exceeded. Try again later.');\n}\n\n// Proceed with upload...\n```\n\n### Virus Scanning\n\n```php\n\u003c?php\n\nuse Farisc0de\\PhpFileUploading\\Security\\ClamAvScanner;\n\n$scanner = new ClamAvScanner(\n    socketPath: '/var/run/clamav/clamd.sock'\n);\n\nif ($scanner-\u003eisAvailable()) {\n    $result = $scanner-\u003escan($file-\u003egetTempName());\n    \n    if ($result-\u003eisInfected()) {\n        die('Virus detected: ' . $result-\u003egetVirusName());\n    }\n}\n```\n\n### Event System\n\n```php\n\u003c?php\n\nuse Farisc0de\\PhpFileUploading\\Events\\EventDispatcher;\nuse Farisc0de\\PhpFileUploading\\Events\\UploadEvents;\nuse Farisc0de\\PhpFileUploading\\Events\\FileEvent;\n\n$dispatcher = new EventDispatcher();\n\n// Log all uploads\n$dispatcher-\u003eaddListener(UploadEvents::AFTER_UPLOAD, function (FileEvent $event) {\n    $logger-\u003einfo('File uploaded: ' . $event-\u003egetFilename());\n});\n\n// Block certain file types\n$dispatcher-\u003eaddListener(UploadEvents::BEFORE_VALIDATION, function (FileEvent $event) {\n    $file = $event-\u003egetFile();\n    if (str_ends_with($file-\u003egetName(), '.exe')) {\n        $event-\u003estopPropagation();\n        throw new \\Exception('EXE files are not allowed');\n    }\n});\n```\n\n### Storage Abstraction\n\n```php\n\u003c?php\n\nuse Farisc0de\\PhpFileUploading\\Storage\\LocalStorage;\nuse Farisc0de\\PhpFileUploading\\Storage\\StorageManager;\n\n// Single disk\n$storage = new LocalStorage('/var/www/uploads', 0755, 0644, 'https://example.com/uploads');\n\n$storage-\u003ewrite('path/to/file.jpg', $contents);\n$url = $storage-\u003epublicUrl('path/to/file.jpg');\n\n// Multiple disks\n$manager = new StorageManager();\n$manager-\u003ecreateLocalDisk('uploads', '/var/www/uploads', 'https://example.com/uploads');\n$manager-\u003ecreateLocalDisk('temp', '/tmp/uploads');\n\n$manager-\u003edisk('uploads')-\u003ewrite('file.jpg', $contents);\n```\n\n### Logging\n\n```php\n\u003c?php\n\nuse Farisc0de\\PhpFileUploading\\Logging\\FileLogger;\nuse Farisc0de\\PhpFileUploading\\Logging\\LogLevel;\n\n$logger = new FileLogger('/var/log/uploads.log', LogLevel::INFO);\n\n$upload-\u003esetLogger($logger);\n$validator-\u003esetLogger($logger);\n```\n\n### Image Processing\n\n```php\n\u003c?php\n\nuse Farisc0de\\PhpFileUploading\\Image;\n\n$image = new Image();\n\n// Resize\n$image-\u003eresize('source.jpg', 'thumb.jpg', 200, 200);\n\n// Compress\n$image-\u003ecompress('source.jpg', 'compressed.jpg', 75);\n\n// Add watermark\n$image-\u003eaddWatermark('source.jpg', 'watermark.png', 'output.jpg', 'bottom-right');\n\n// Convert format\n$image-\u003econvert('source.png', 'output.webp', 'webp', 80);\n```\n\n## Configuration\n\n### Filter Configuration (filter.json)\n\nThe library uses a JSON configuration file for extension/MIME mappings and size limits:\n\n```json\n{\n    \"extensions\": {\n        \"jpg\": \"image/jpeg\",\n        \"png\": \"image/png\",\n        \"pdf\": \"application/pdf\"\n    },\n    \"forbidden\": [\n        \"shell.php\",\n        \"backdoor.php\",\n        \".htaccess\"\n    ],\n    \"size_limits\": {\n        \"image\": \"10 MB\",\n        \"document\": \"20 MB\",\n        \"video\": \"100 MB\",\n        \"default\": \"50 MB\"\n    },\n    \"categories\": {\n        \"images\": [\"image/jpeg\", \"image/png\", \"image/gif\"],\n        \"documents\": [\"application/pdf\", \"application/msword\"]\n    }\n}\n```\n\n## Exception Handling\n\nThe library provides specific exception types for different error scenarios:\n\n```php\nuse Farisc0de\\PhpFileUploading\\Exception\\ValidationException;\nuse Farisc0de\\PhpFileUploading\\Exception\\StorageException;\nuse Farisc0de\\PhpFileUploading\\Exception\\FileNotFoundException;\nuse Farisc0de\\PhpFileUploading\\Exception\\ConfigurationException;\nuse Farisc0de\\PhpFileUploading\\Exception\\ImageException;\n\ntry {\n    $upload-\u003eupload();\n} catch (ValidationException $e) {\n    // Handle validation errors\n    echo \"Validation failed: \" . $e-\u003egetMessage();\n    echo \"Type: \" . $e-\u003egetValidationType();\n    print_r($e-\u003egetContext());\n} catch (StorageException $e) {\n    // Handle storage errors\n} catch (FileNotFoundException $e) {\n    // Handle missing files\n}\n```\n\n## Testing\n\n```bash\n# Run tests\ncomposer test\n\n# Run tests with coverage\ncomposer test-coverage\n\n# Static analysis\ncomposer phpstan\n\n# Code style check\ncomposer cs-check\n```\n\n## Directory Structure\n\n```\nsrc/\n├── Exception/          # Custom exception classes\n├── Events/             # Event system\n├── Logging/            # PSR-3 logging\n├── RateLimiting/       # Rate limiting\n├── Security/           # Virus scanning\n├── Storage/            # Storage abstraction\n├── Validation/         # Validation system\n│   └── Validators/     # Individual validators\n├── File.php            # File representation\n├── Image.php           # Image processing\n├── Upload.php          # Main upload handler\n├── Utility.php         # Helper functions\n└── filter.json         # Default filter config\n```\n\n## Security Best Practices\n\n1. **Always validate file types** using both extension and MIME type checking\n2. **Use hashed filenames** to prevent overwriting and path traversal\n3. **Store uploads outside web root** when possible\n4. **Enable virus scanning** in production environments\n5. **Implement rate limiting** to prevent abuse\n6. **Set appropriate file permissions** (0644 for files, 0755 for directories)\n7. **Use HTTPS** for file uploads\n8. **Validate image dimensions** to prevent resource exhaustion\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Credits\n\nDeveloped by [FarisCode](https://github.com/farisc0de)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffarisc0de%2Fphpfileuploading","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffarisc0de%2Fphpfileuploading","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffarisc0de%2Fphpfileuploading/lists"}