Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Base64 Bundle Laravel Package

tiloweb/base64-bundle

A small Symfony bundle that adds Base64 encoding and decoding helpers, including Twig filters, so you can transform strings directly in templates or services without writing custom code.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and confirm compatibility

composer require tiloweb/base64-bundle

The last release is from June 2020, so before anything else open the package's composer.json and check the require block for symfony/form and symfony/framework-bundle. If you're on Symfony 6/7, treat this as a "read the source and copy it" exercise rather than a drop-in dependency.

2. Register the bundle

Symfony Flex auto-registers packages typed symfony-bundle; if it wasn't added, do it manually in config/bundles.php:

return [
    // ...
    Tiloweb\Base64Bundle\TilowebBase64Bundle::class => ['all' => true],
];

Confirm the exact FQCN from the bundle class file — the repo (SymfonyBase64Bundle) and package name (base64-bundle) don't match cleanly, so guessing the namespace will cost you ten minutes.

3. Where to look first

  • src/Form/Type/ — the form type you'll actually use
  • src/Form/DataTransformer/ — the UploadedFile → data:image/...;base64,... conversion, i.e. the whole value of the package
  • Resources/config/ (or config/) — service definitions and any parameters
  • README.md — for a 2-star bundle this is usually the only documentation
  • composer.json — supported Symfony range, PSR-4 mapping

4. First use case — an avatar field with no file storage

// src/Form/ProductType.php
use Tiloweb\Base64Bundle\Form\Type\Base64ImageType;

$builder
    ->add('name', TextType::class)
    ->add('photo', Base64ImageType::class, ['required' => false]);

The entity property is just a string:

#[ORM\Column(type: 'text', nullable: true)]
private ?string $photo = null; // "data:image/png;base64,iVBORw0KGgo..."

Because the value is already a self-contained data URI, rendering needs no asset pipeline, no storage adapter and no cleanup job:

{% if product.photo %}
    <img src="{{ product.photo }}" alt="{{ product.name }}" width="64" height="64">
{% endif %}

Implementation Patterns

Upload → base64 in a single field. The type wraps a file input and a transformer that reads the upload and replaces the submitted value with a data:{mime};base64,{payload} string before it reaches your model. So $form->getData()->getPhoto() returns a string, not an UploadedFile, and your controller stays trivial:

$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
    $em->persist($product);
    $em->flush();
}

Editing records without clobbering the image. Submitting the form replaces the stored string, so add an explicit "keep current" branch:

$current = $product->getPhoto();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
    if ($product->getPhoto() === null) {
        $product->setPhoto($current);
    }
    $em->flush();
}

Check the bundle's transformer first — some implementations already no-op on empty input, in which case you don't need this.

API / JSON payloads. If the front end posts a canvas toDataURL() string, the bundle adds little: validate and persist the string directly. Reach for the form type only when the input is a real multipart file upload.

EasyAdmin / Sonata. Register it as a form type and render the raw string in the list template — never wrap it in asset():

yield Field::new('photo')->setFormType(Base64ImageType::class);

Validation belongs on the property, not the type:

#[Assert\Length(max: 200_000)] // ~150 KB decoded
#[Assert\Regex('/^data:image\/(png|jpe?g|webp);base64,/')]
private ?string $photo = null;

Extracting the raw bytes downstream (thumbnailing, hashing, dedupe):

[$meta, $payload] = explode(',', $dataUri, 2);
$mime  = explode(';', explode(':', $meta)[1])[0]; // image/png
$bytes = base64_decode($payload);

Good fit: avatars, logos, small icons, seeded demo data. Bad fit: anything a user might upload from a phone camera.

Gotchas and Tips

  • Maintenance risk is the headline. Last release mid-2020, 2 stars, zero dependents, no CI. The actual payload of this bundle is roughly one form type and one data transformer. If it fights your Symfony version, fork it or copy those two classes into src/Form/ — you'll spend less time than debugging it.
  • GPL-3.0 is copyleft. Dropping this into a proprietary SaaS is a licensing conversation most teams don't want. For ~100 lines of code, clean-room reimplementation is usually the cheaper path.
  • Base64 is ~33% larger than the binary. Plan the column as TEXT/LONGTEXT (Postgres: text), and check post_max_size, upload_max_filesize and MySQL's max_allowed_packet before blaming the bundle for silent empty submissions.
  • Don't store large images in the database. It inflates row size, wrecks SELECT * plans, and bloats backups. Cap dimensions and byte size client-side as well as server-side.
  • Don't use the data URI in CSS url() or <a href> for anything reused. It's re-sent on every request and defeats HTTP caching entirely. Hash-named files win for shared assets.
  • MIME type is unverified. The transformer encodes whatever was uploaded. Validate the real content server-side with getimagesize() or finfo — never trust the browser-supplied type baked into the data URI.
  • FQCN vs. legacy alias. Older bundles register ->add('photo', 'tiloweb_base64_image'). Modern Symfony wants the class name. If you hit a Twig "block not found" error, check getBlockPrefix() and whether the bundle ships its widget template under Resources/views/Form/; you may need to register it yourself.
  • Debugging the transformer. Use the profiler's Form panel, or dump($form->get('photo')->getData()) in a PRE_SUBMIT listener to see the raw upload before conversion. If the entity ends up holding an UploadedFile, the transformer never ran — check service registration and autoconfigure tags in services.yaml.
  • The data transformer is the only real extension point. If the emitted prefix, whitespace or mime format doesn't match your API contract, attach your own DataTransformerInterface via ->addModelTransformer() rather than editing the bundle.
  • Write two tests of your own: one asserting the stored value starts with data:image/, and one asserting an oversized upload is rejected. There are none upstream.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle