Install the bundle via Composer:
composer require 1tomany/data-uri-bundle
First Use Case: Embed a file (e.g., an image) directly in a Symfony API response as a Data URI.
Create a DTO/Entity implementing OneToMany\DataUri\Contract\Record\DataUriInterface:
use OneToMany\DataUri\Contract\Record\DataUriInterface;
class ProductImage implements DataUriInterface
{
private string $path;
public function __construct(string $path)
{
$this->path = $path;
}
public function getPath(): string
{
return $this->path;
}
}
Use the Denormalizer in your API response (e.g., with API Platform or Symfony Serializer):
use Symfony\Component\Serializer\Annotation\Context;
class ProductDto
{
#[Context(['serializer_groups' => ['default']])]
public ProductImage $image;
}
Test with the CLI Command (optional):
php bin/console onetomany:data-uri:encode-file /path/to/image.png
Auto-Denormalization: The bundle auto-registers DataUriNormalizer for DataUriInterface. No manual configuration is needed for basic use.
Serializer Groups: Use @Context or #[Groups] to control when Data URIs are embedded:
use Symfony\Component\Serializer\Annotation\Groups;
class ProductDto
{
#[Groups(['api'])]
public ProductImage $thumbnail;
}
Custom Normalization: Extend DataUriNormalizer to add logic (e.g., size limits):
use OneToMany\DataUriBundle\Serializer\DataUriNormalizer;
class CustomDataUriNormalizer extends DataUriNormalizer
{
public function normalize($object, string $format = null, array $context = [])
{
if ($this->shouldSkip($object)) {
return $object->getPath(); // Fallback to URL
}
return parent::normalize($object, $format, $context);
}
private function shouldSkip(DataUriInterface $uri): bool
{
$fileSize = filesize($uri->getPath());
return $fileSize > 1_000_000; // Skip files >1MB
}
}
Register it in config/services.yaml:
services:
App\Serializer\CustomDataUriNormalizer:
tags: ['serializer.normalizer']
php bin/console onetomany:data-uri:encode-file assets/logo.png > logo.datauri
php bin/console onetomany:data-uri:encode-file assets/background.jpg | xargs -I{} echo "background-image: url({});" >> styles.css
/uploads/images/).DataUriInterface:
use League\Flysystem\FilesystemOperator;
class S3ProductImage implements DataUriInterface
{
private FilesystemOperator $filesystem;
private string $path;
public function __construct(FilesystemOperator $filesystem, string $path)
{
$this->filesystem = $filesystem;
$this->path = $path;
}
public function getPath(): string
{
return $this->filesystem->readStream($this->path);
}
}
{
"product": {
"name": "Widget",
"thumbnail": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."
}
}
?embed=thumbnail):
// In your controller
$context = ['embed' => $request->query->get('embed')];
return $this->serializer->serialize($dto, 'json', $context);
Large File Bloat:
File Path Security:
getPath() returns raw paths. Validate inputs to prevent:
../../../etc/passwd).public function getPath(): string
{
return realpath($this->path) ?: $this->path;
}
Serializer Conflicts:
DataUriNormalizer may be ignored.config/services.yaml:
tags: ['serializer.normalizer', { name: 'serializer.normalizer', priority: 100 }]
Binary Data Corruption:
getPath() returns a valid stream or binary-safe string.Non-Symfony Projects:
1tomany/data-uri package directly.Check Normalizer Registration:
php bin/console debug:container OneToMany\DataUriBundle\Serializer\DataUriNormalizer
serializer.normalizer and serializer.denormalizer tags.Inspect Serialization Context:
#[Context(['debug' => true])]
public ProductImage $image;
debug context values.CLI Command Issues:
onetomany:data-uri:encode-file fails:
chmod -R 755 /path/to/files).Performance Bottlenecks:
$event = new GetDataUriEvent($filePath);
$this->dispatcher->dispatch($event, DataUriEvents::ENCODE);
Custom Data URI Formats:
DataUriNormalizer to support custom MIME types or encoding options:
public function normalize($object, string $format = null, array $context = [])
{
$mimeType = $context['mime_type'] ?? 'application/octet-stream';
return 'data:' . $mimeType . ';base64,' . base64_encode(file_get_contents($object->getPath()));
}
Async Encoding:
use OneToMany\DataUri\Message\EncodeDataUriMessage;
$bus->dispatch(new EncodeDataUriMessage($filePath));
Flysystem Integration:
DataUriInterface adapter for cloud storage:
class CloudDataUri implements DataUriInterface
{
private FilesystemOperator $filesystem;
private string $path;
public function getPath(): string
{
return $this->filesystem->readStream($this->path);
}
}
Validation Rules:
DataUriInterface implementations:
use Symfony\Component\Validator\Constraints as Assert;
class ProductImage implements DataUriInterface
{
#[Assert\File(maxSize: '1M')]
private string $path;
}
No config/packages/ File Needed:
data_uri.yaml—it’s unnecessary.Serializer Groups:
How can I help you explore Laravel packages today?