tiloweb/uploaded-file-type-bundle
Composer 安装命令:
composer require tiloweb/uploaded-file-type-bundle
包简介
A Symfony bundle that handles file uploads via forms and stores the URL automatically using Flysystem
README 文档
README
A Symfony bundle that handles file uploads via forms and automatically stores the resulting URL in your entity. No more manual file handling in controllers!
✨ Features
- 🚀 Zero-configuration file uploads - Just add an option to your form field
- 📦 Flysystem integration - Works with any storage backend (local, S3, GCS, SFTP, etc.)
- 🔄 Automatic URL storage - The file URL is stored directly in your entity
- 🎯 Custom naming strategies - Full control over uploaded file names
- 🗑️ Auto-cleanup - Optionally delete previous files when uploading new ones
- 🎨 Twig integration - Preview uploaded images in your forms
📋 Requirements
| Version | PHP | Symfony |
|---|---|---|
| 2.x | ≥ 8.1 | 6.4, 7.x, 8.x |
| 1.x | ≥ 8.1 | 6.x, 7.x |
📥 Installation
composer require tiloweb/uploaded-file-type-bundle
If you're not using Symfony Flex, add the bundle manually:
// config/bundles.php return [ // ... Tiloweb\UploadedFileTypeBundle\UploadedFileTypeBundle::class => ['all' => true], ];
⚙️ Configuration
Step 1: Configure Flysystem
First, configure your filesystem adapter using the OneupFlysystemBundle:
# config/packages/oneup_flysystem.yaml oneup_flysystem: adapters: default_adapter: local: location: '%kernel.project_dir%/public/uploads' filesystems: default_filesystem: adapter: default_adapter alias: League\Flysystem\Filesystem
Step 2: Configure Upload Destinations
# config/packages/uploaded_file_type.yaml uploaded_file_type: configurations: # Default configuration for general uploads default: filesystem: 'oneup_flysystem.default_filesystem' base_uri: 'https://example.com/uploads' path: '/files' # Separate configuration for user avatars avatars: filesystem: 'oneup_flysystem.default_filesystem' base_uri: 'https://example.com/uploads' path: '/avatars' # S3 configuration for large files documents: filesystem: 'oneup_flysystem.s3_filesystem' base_uri: 'https://cdn.example.com' path: '/documents'
Configuration Options
| Option | Type | Required | Description |
|---|---|---|---|
filesystem |
string | ✅ | The Flysystem filesystem service ID |
base_uri |
string | ❌ | The base URL for accessing uploaded files |
path |
string | ❌ | The subdirectory path within the filesystem |
🚀 Usage
Basic Usage
Simply add the upload option to any FileType field:
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\FormBuilderInterface; class ProductType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('name') ->add('image', FileType::class, [ 'upload' => 'default', // Use the 'default' configuration 'required' => false, ]) ; } }
That's it! When the form is submitted:
- The file is uploaded to your configured filesystem
- The URL is automatically stored in the
$imageproperty - No additional controller code needed!
Custom Filename Strategy
Control how files are named when uploaded:
$builder->add('avatar', FileType::class, [ 'upload' => 'avatars', 'filename' => function (UploadedFile $file, User $user): string { return sprintf( 'user_%d_%s.%s', $user->getId(), bin2hex(random_bytes(8)), $file->guessClientExtension() ?? 'bin' ); }, ]);
Disable Auto-Cleanup
By default, the previous file is deleted when uploading a new one. Disable this behavior:
$builder->add('document', FileType::class, [ 'upload' => 'documents', 'delete_previous' => false, // Keep old files ]);
Available Form Options
| Option | Type | Default | Description |
|---|---|---|---|
upload |
string | - | The configuration name to use |
filename |
callable | auto | Custom filename generator |
delete_previous |
bool | true |
Delete previous file on update |
📖 Complete Example
Entity
namespace App\Entity; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] class Product { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(length: 255)] private string $name = ''; #[ORM\Column(length: 500, nullable: true)] private ?string $image = null; // Getters and setters... public function getImage(): ?string { return $this->image; } public function setImage(?string $image): static { $this->image = $image; return $this; } }
Form
namespace App\Form; use App\Entity\Product; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraints\Image; class ProductType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('name', TextType::class, [ 'label' => 'Product Name', ]) ->add('image', FileType::class, [ 'upload' => 'default', 'required' => false, 'label' => 'Product Image', 'constraints' => [ new Image([ 'maxSize' => '5M', 'mimeTypes' => ['image/jpeg', 'image/png', 'image/webp'], ]), ], ]) ; } public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Product::class, ]); } }
Controller
namespace App\Controller; use App\Entity\Product; use App\Form\ProductType; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; class ProductController extends AbstractController { #[Route('/product/new', name: 'product_new')] public function new(Request $request, EntityManagerInterface $em): Response { $product = new Product(); $form = $this->createForm(ProductType::class, $product); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em->persist($product); $em->flush(); // $product->getImage() now contains the URL! // e.g., "https://example.com/uploads/files/product_a1b2c3d4.jpg" return $this->redirectToRoute('product_show', ['id' => $product->getId()]); } return $this->render('product/new.html.twig', [ 'form' => $form, ]); } }
Twig Template
The bundle provides a form theme that displays the current image:
{# templates/product/new.html.twig #} {% extends 'base.html.twig' %} {% block body %} <h1>New Product</h1> {{ form_start(form) }} {{ form_row(form.name) }} {{ form_row(form.image) }} {# Shows current image if exists #} <button type="submit">Save</button> {{ form_end(form) }} {% endblock %}
🎨 Customizing the Form Theme
Override the default template to customize how uploaded files are displayed:
{# templates/form/uploaded_file.html.twig #} {% extends '@UploadedFileType/form.html.twig' %} {% block file_widget %} {{ parent() }} {% if url is defined and url is not null %} <div class="uploaded-file-preview"> {% if url matches '/\\.(jpg|jpeg|png|gif|webp)$/i' %} <img src="{{ url }}" alt="Preview" class="preview-image"> {% else %} <a href="{{ url }}" target="_blank">View current file</a> {% endif %} </div> {% endif %} {% endblock %}
Register your custom theme:
# config/packages/twig.yaml twig: form_themes: - 'form/uploaded_file.html.twig'
🔧 Advanced Usage
Using the Service Directly
use Tiloweb\UploadedFileTypeBundle\UploadedFileTypeService; class MyService { public function __construct( private UploadedFileTypeService $uploadService, ) {} public function uploadFile(UploadedFile $file): string { return $this->uploadService->upload( filename: 'custom-name.pdf', uploadedFile: $file, configuration: 'documents' ); } public function deleteFile(string $url): bool { return $this->uploadService->delete($url, 'documents'); } public function fileExists(string $url): bool { return $this->uploadService->exists($url, 'documents'); } }
Cloud Storage Examples
Amazon S3
# config/packages/oneup_flysystem.yaml oneup_flysystem: adapters: s3_adapter: awss3v3: client: Aws\S3\S3Client bucket: '%env(AWS_S3_BUCKET)%' prefix: uploads filesystems: s3_filesystem: adapter: s3_adapter # config/packages/uploaded_file_type.yaml uploaded_file_type: configurations: s3: filesystem: 'oneup_flysystem.s3_filesystem' base_uri: 'https://%env(AWS_S3_BUCKET)%.s3.%env(AWS_REGION)%.amazonaws.com' path: '/uploads'
Google Cloud Storage
oneup_flysystem: adapters: gcs_adapter: googlecloudstorage: client: Google\Cloud\Storage\StorageClient bucket: '%env(GCS_BUCKET)%' filesystems: gcs_filesystem: adapter: gcs_adapter uploaded_file_type: configurations: gcs: filesystem: 'oneup_flysystem.gcs_filesystem' base_uri: 'https://storage.googleapis.com/%env(GCS_BUCKET)%' path: '/uploads'
🧪 Testing
# Run tests composer test # Run static analysis composer phpstan # Fix coding standards composer cs-fix
🤝 Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This bundle is released under the MIT License.
🙏 Credits
- Thibault HENRY - Creator
- All Contributors
🔗 Links
tiloweb/uploaded-file-type-bundle 适用场景与选型建议
tiloweb/uploaded-file-type-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 9.55k 次下载、GitHub Stars 达 0, 最近一次更新时间为 2021 年 04 月 28 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「symfony」 「file」 「storage」 「s3」 「form」 「bundle」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 tiloweb/uploaded-file-type-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 tiloweb/uploaded-file-type-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 tiloweb/uploaded-file-type-bundle 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A SDK for working with B2 cloud storage.
Small library to access Microsoft Windows Azure Blob Storage with a Service or a StreamWrapper.
The file manager intended for using Laravel with CKEditor / TinyMCE / Colorbox
The bundle for easy using json-rpc api on your project
Bundle Symfony DaplosBundle
Laravel Media Popup to upload/view the files
统计信息
- 总下载量: 9.55k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 16
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2021-04-28