chillerlan/php-qrcode
Generate and read QR codes in PHP with a modern, namespaced library. Supports Model 2 QR Codes (versions 1–40), ECC levels L/M/Q/H, mixed encoding modes, multiple output formats, and includes a QR Code reader based on ZXing.
Installation:
composer require chillerlan/php-qrcode
Ensure PHP 8.4+ with ext-mbstring and optionally ext-gd/ext-imagick for image output.
First Use Case: Generate a QR code from a string and output it directly:
$qrCode = new \chillerlan\QRCode\QRCode();
echo $qrCode->render('https://example.com');
This outputs a Base64-encoded data URI (e.g., data:image/png;base64,...).
Where to Look First:
Instantiation:
// Default options
$qrCode = new \chillerlan\QRCode\QRCode();
// Custom options (v6+)
$options = new \chillerlan\QRCode\QROptions([
'version' => 10,
'eccLevel' => \chillerlan\QRCode\EccLevel::H,
]);
$qrCode = new \chillerlan\QRCode\QRCode($options);
Rendering:
echo '<img src="' . $qrCode->render('data') . '" alt="QR Code" />';
$qrCode->render('data', 'path/to/qrcode.png');
$qrCode->getOptions()->outputInterface = \chillerlan\QRCode\QRGdImage::class;
$qrCode->getOptions()->returnResource = true;
$resource = $qrCode->render('data');
Reading QR Codes:
$reader = new \chillerlan\QRCode\QRReader();
$result = $reader->read('path/to/qrcode.png');
echo $result->getData(); // Extracted data
$qrCode->getOptions()->version = 5; // Modify after instantiation
$qrCode->clearSegments()
->addNumericSegment('12345')
->addAlphaNumSegment('ABCD')
->addByteSegment(\chillerlan\QRCode\QRDataMode::ECI_UTF8, '日本語');
$qrCode->getOptions()->outputType = \chillerlan\QRCode\QROutputInterface::GDIMAGE_SVG;
// In a Blade view
{!! \chillerlan\QRCode\QRCode::format('png')->size(300)->render('data') !!}
return response()->json([
'qr_code' => $qrCode->render('data'),
]);
// Dispatch a job to generate QR codes asynchronously
GenerateQRCode::dispatch($data, $path);
Output Format Mismatch:
ext-gd or ext-imagick is installed for image outputs.$options->outputBase64 = false.Character Encoding:
mb_internal_encoding('UTF-8') for non-ASCII data (e.g., Japanese/Chinese).if (!\chillerlan\QRCode\QRDataMode\Hanzi::validateString($data)) {
throw new \InvalidArgumentException('Invalid Hanzi data');
}
Version/Size Limits:
$qrCode->getOptions()->version = 40 if data exceeds limits.Reader Limitations:
ext-gd/ext-imagick).Caching:
cachefile in QROptions saves rendered QR codes to disk. Clear manually if needed:
if (file_exists($options->cachefile)) {
unlink($options->cachefile);
}
$qrCode->getOptions()->debug = true; // Logs warnings/errors
$matrix = $qrCode->getQRMatrix();
var_dump($matrix->getMatrix()); // Debug module layout
QRDataModeInterface::validateString() for each segment type before encoding.Custom Output Modules:
Implement QROutputInterface for new formats (e.g., WebP):
class QRWebP implements QROutputInterface {
public function render(QRMatrix $matrix, QROptions $options): string {
// Custom logic
}
}
Register via:
$qrCode->getOptions()->outputInterface = QRWebP::class;
Extend QROptions:
Add custom settings via traits or inheritance:
class CustomOptions extends \chillerlan\QRCode\QROptions {
protected string $customParam = 'default';
}
Override Defaults:
Use setOptions() or pass options directly to the constructor:
$qrCode = new \chillerlan\QRCode\QRCode([
'outputType' => QROutputInterface::GDIMAGE_SVG,
'size' => 500,
]);
QRCode instances with shared options for repeated generations.QRMatrix for manual control:
$matrix = $qrCode->getQRMatrix();
$qrCode->renderMatrix($matrix, 'output.png');
$this->app->singleton(\chillerlan\QRCode\QRCode::class, function ($app) {
return new \chillerlan\QRCode\QRCode($app['config']['qrcode.options']);
});
php artisan vendor:publish --provider="chillerlan\QRCode\QRCodeServiceProvider"
How can I help you explore Laravel packages today?