How to save generated qr Code in laravel?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# How to Save Generated QR Codes in Laravel: A Developer's Guide
As developers, we often deal with generating dynamic assets, like images or PDFs, within our backend processes. When using a package like `simplesoftwareio/simple-qrcode` in a Laravel application, the immediate goal is not just to display the result but to persist that generated image onto the server's local filesystem or cloud storage.
This guide will walk you through the practical steps of taking the QR code generated by the library and successfully saving it to your local drive using standard Laravel practices.
## Understanding the Generation Process
The provided snippet demonstrates how you generate the QR code:
```php
public function qr($id)
{
$data = Ticket::get()->find($id);
$image = \QrCode::format('png')
->merge('img/t.jpg', 0.1, true)
->size(200)->errorCorrection('H')
->generate('A simple example of QR code!');
return response($image)->header('Content-type','image/png');
}
```
Currently, this method returns the raw image data directly as an HTTP response. While this is useful for immediate display in a browser, it doesn't save the file to the disk. To achieve local saving, we need to intercept the generated binary data and write it using PHP's file system functions or Laravelâs robust `Storage` facade.
## Method 1: Saving the Image using the Laravel Storage Facade (Recommended)
The most idiomatic way to handle file storage in a modern Laravel application is by utilizing the `Storage` facade. This approach keeps your application decoupled from specific file system details and makes scaling easier, which aligns perfectly with the principles of clean architecture often promoted by the Laravel ecosystem.
To save the generated image, you first need to ensure the image data is available as a stream or string, and then use the storage class.
Here is how you can modify your controller method to save the file:
```php
use Illuminate\Support\Facades\Storage;
use SimpleSoftwareIO\QrCode\Facades\QrCode; // Assuming this namespace
public function generateAndSaveQr($id)
{
$data = \App\Models\Ticket::find($id); // Using Eloquent for data retrieval
if (!$data) {
return response()->json(['error' => 'Ticket not found'], 404);
}
// 1. Generate the QR Code as a stream
$qrCodeStream = \QrCode::format('png')
->merge('img/t.jpg', 0.1, true)
->size(200)
->errorCorrection('H')
->generate('A simple example of QR code!');
// 2. Define the file path and name
$filename = 'tickets/' . $data->id . '_qr.png'; // Save in a dedicated directory
// 3. Store the stream directly to the disk
// The putStream method handles writing the raw binary data efficiently.
Storage::disk('public')->put($filename, $qrCodeStream);
// 4. Return a response indicating success or redirect
return response()->json([
'message' => 'QR Code successfully generated and saved.',
'path' => Storage::url($filename)
]);
}
```
**Key Takeaways from this approach:**
1. **Stream Handling:** We capture the output of `generate()` as a stream (`$qrCodeStream`) instead of letting it immediately return an HTTP response.
2. **`Storage` Facade:** We leverage `Storage::disk('public')->put(...)` to handle the actual file writing. This is superior to manually using `file_put_contents()` because it integrates seamlessly with Laravel's configuration for disk management (local, S3, etc.).
3. **Organization:** Storing files in a dedicated directory structure (`tickets/`) keeps your application organized, which is crucial when managing assets within a large system built on the Laravel framework. Remember that good architecture, much like robust database design, relies on clear separation of concerns!
## Best Practices for File Handling
When working with file operations in Laravel, keep these best practices in mind:
* **Disk Configuration:** Always define your storage disks in `config/filesystems.php`. Using the default `public` disk is ideal for assets that need to be accessible via a web URL.
* **Permissions:** Ensure your web server (like Apache or Nginx) has the necessary write permissions to the storage directory defined in `storage/app/public` (or wherever you configure your public disk).
* **Error Handling:** Always wrap file operations in `try...catch` blocks to gracefully handle potential issues like permission errors or disk space limitations.
## Conclusion
Saving generated files is a fundamental task in backend development. By moving away from returning raw responses and instead utilizing Laravelâs built-in `Storage` facade, we transform a simple image generation script into a robust, scalable asset management solution. This approach ensures that your application remains clean, maintainable, and adheres to the principles of modern software development, making it an excellent pattern for anyone building applications on the Laravel platform.