Builder & options
Qr::…() returns an immutable PendingQr: every call returns a modified copy, so a configured builder is safe to reuse. Every option at once:
use RoundlyConsulting\Qr\Enums\{EciMode, ErrorCorrection, FinderStyle, ModuleStyle, Segmentation, Sensitivity};
$svg = Qr::text('ABC-123')
->errorCorrection(ErrorCorrection::High) // or 'H'
->versions(2, 10) // or ->version(5)
->mask(3) // null = automatic
->boostErrorCorrection(false)
->eci(EciMode::Never)
->segmentation(Segmentation::Optimal) // Optimal | Single | Byte
->kanji()
->size(null) // responsive (no width/height)
->margin(4)
->foreground('#1a1a1a')
->background('transparent')
->moduleStyle(ModuleStyle::Rounded, 0.35)
->finderStyle(FinderStyle::Rounded, '#0a58ca')
->title('Order ABC-123')
->description('Opens the order page')
->xmlDeclaration()
->sensitivity(Sensitivity::Public)
->svg();Method reference
| Group | Methods |
|---|---|
| Encoding | errorCorrection(ErrorCorrection|string), version(int), versions(int, int), mask(?int), boostErrorCorrection(bool = true), eci(EciMode), segmentation(Segmentation), kanji(bool = true) |
| Rendering | size(?int), margin(int), foreground(string), background(string), moduleStyle(ModuleStyle, ?float $radius), finderStyle(FinderStyle, ?string $color), title(?string), description(?string), xmlDeclaration(bool = true) |
| Policy | sensitivity(Sensitivity), withOptions(QrOptions) |
| Terminals | matrix(): QrMatrix, info(): EncodingInfo, fits(): bool (would matrix() succeed? — no symbol built), svg(): Svg, toDataUri(DataUriEncoding), toHtml(), toResponse($request), __toString(), payload(): Payload |
Setters validate immediately — an out-of-range size, margin, mask or radius throws InvalidOptionException, an unknown colour InvalidColorException.
One-call options form
Pass a QrOptions DTO to Qr::svg() / Qr::matrix() / Qr::info(), or apply one to an existing builder with withOptions():
use RoundlyConsulting\Qr\DataTransferObjects\QrOptions;
$svg = Qr::svg('https://example.com', new QrOptions(size: 200, errorCorrection: ErrorCorrection::Medium));
$matrix = Qr::matrix('hello', new QrOptions(mask: 2));
$info = Qr::info('hello', new QrOptions(errorCorrection: ErrorCorrection::High)); // EncodingInfo
$svg = Qr::text('hi')->withOptions(new QrOptions(foreground: '#333333'))->svg();Every QrOptions field is nullable; null means not set, so the payload or the config decides:
new QrOptions( // every field nullable; null = not set (payload / config decide)
size: 200, margin: 2, errorCorrection: ErrorCorrection::Quartile, minVersion: 1, maxVersion: 10,
mask: null, foreground: '#111111', background: 'transparent', moduleStyle: ModuleStyle::Rounded,
finderStyle: FinderStyle::Rounded, title: 'Menu', description: null, eci: EciMode::Never,
sensitivity: Sensitivity::Public,
);Precedence and locks
- Explicit builder calls and withOptions() write the same slots — last write wins.
- Then the payload’s requirements (PayloadRequirements).
- Then the configuration.
- A payload’s maximum version is a hard cap.
- Options a payment standard fixes (EPC: level M, byte mode, no ECI, no boost; PAY by square: one alphanumeric segment, no ECI) throw InvalidOptionException at the terminal call when overridden with a different value — the same value is a no-op.
Title and description
The accessible title defaults to the qr::qr.title translation (“QR code”); the description defaults to a per-payload translation (qr::qr.descriptions.*) that never interpolates a secret, name, IBAN or amount — URL codes mention only the host. Override either with title() / description().
Enums
| Enum | Cases |
|---|---|
ErrorCorrection | Low (L), Medium (M), Quartile (Q), High (H) — recoveryPercent(), stronger(), tryFromInput() |
EciMode | Auto, Always, Never |
Segmentation | Optimal, Single, Byte |
ModuleStyle | Square, Rounded, Dots |
FinderStyle | Square, Rounded |
DataUriEncoding | Percent, Base64 |
Sensitivity | Public, Personal, Secret — isCacheable(), cacheControl() |
Every enum is backed and carries the enums-for-laravel helpers, so each one can feed a select or a validation rule directly.
Inspecting a code
$matrix = Qr::matrix('HELLO WORLD'); // QrMatrix: version(), mask(), isDark($x, $y), rows()
$info = Qr::text('HELLO WORLD')->info(); // EncodingInfo: segments, data/capacity bits, mask penalties
echo $matrix->toText(); // debug print in the terminalShow your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.