QR-Codes sind zweidimensionale Barcodes, die Text, URLs oder andere Daten maschinenlesbar speichern. Mit PHP lassen sich solche Codes programmatisch erzeugen und als PNG-Datei speichern oder direkt im Browser anzeigen. Dieses Tutorial zeigt die Installation der Bibliothek chillerlan/php-qrcode per Composer und erklärt die wichtigsten Optionen für die QR-Code-Generierung.

Bevor der erste QR-Code erzeugt werden kann, müssen einige Voraussetzungen auf dem Server erfüllt sein.
Voraussetzungen
Für die Erzeugung von QR-Codes mit PHP werden PHP 8.1 oder höher, Composer und die GD-Extension benötigt. Die GD-Extension ist für die Bildausgabe im PNG-Format zuständig und muss in der php.ini aktiviert sein.
Bibliothek installieren
Die Bibliothek chillerlan/php-qrcode ist eine moderne, aktiv gepflegte Open-Source-Lösung. Die Installation erfolgt über Composer.
<?php
/* Installation per Composer (im Terminal ausführen):
composer require chillerlan/php-qrcode
*/
require_once __DIR__ . '/vendor/autoload.php';
Nach der Installation steht die QRCode-Klasse über den Autoloader zur Verfügung.
Einfachen QR-Code erstellen
Mit wenigen Zeilen Code lässt sich ein QR-Code aus einem beliebigen Text oder einer URL erzeugen.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use chillerlan\QRCode\QRCode;
$qrcode = new QRCode();
$dataUri = $qrcode->render('https://www.beispiel.de');
printf('<img src="%s" alt="QR-Code" />', $dataUri);
Die Methode render() gibt standardmäßig eine Data-URI zurück, die sich direkt in ein HTML-img-Tag einbetten lässt.
QR-Code als PNG speichern
Für die Speicherung als Bilddatei wird ein zweiter Parameter mit dem Dateipfad an render() übergeben.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
$optionen = new QROptions([
'outputType' => QRCode::OUTPUT_IMAGE_PNG,
'scale' => 10,
'eccLevel' => QRCode::ECC_M,
]);
$qrcode = new QRCode($optionen);
$qrcode->render('https://www.beispiel.de', __DIR__ . '/qrcode.png');
echo 'QR-Code wurde als PNG gespeichert.';
Die Option scale bestimmt die Größe jedes einzelnen Moduls in Pixeln. Das eccLevel legt die Fehlerkorrektur fest.
QR-Code direkt im Browser anzeigen
Soll der QR-Code ohne Zwischenspeicherung direkt als Bild ausgeliefert werden, wird der passende HTTP-Header gesetzt.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
$optionen = new QROptions([
'outputType' => QRCode::OUTPUT_IMAGE_PNG,
'scale' => 8,
'imageTransparent' => false,
]);
header('Content-Type: image/png');
$qrcode = new QRCode($optionen);
echo $qrcode->render('https://www.beispiel.de');
Durch den Header Content-Type: image/png interpretiert der Browser die Ausgabe als Bild. Diese Variante eignet sich für dynamische Endpunkte, die QR-Codes auf Anfrage erzeugen.
Optionen und Anpassungen
Die Klasse QROptions bietet zahlreiche Einstellungen. Das folgende Diagramm veranschaulicht den Ablauf der QR-Code-Erzeugung.
flowchart TD
A["Text / URL"] --> B["QRCode-Klasse"]
B --> C{"Ausgabeformat"}
C --> D["PNG-Datei"]
C --> E["Data-URI"]
C --> F["SVG"]
Die Fehlerkorrektur steuert, wie viel vom QR-Code beschädigt sein darf und dennoch lesbar bleibt. Vier Stufen stehen zur Verfügung.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
$optionen = new QROptions([
'outputType' => QRCode::OUTPUT_IMAGE_PNG,
'scale' => 12,
'eccLevel' => QRCode::ECC_H, /* H = höchste Fehlerkorrektur (30%) */
'imageBase64' => false,
]);
$qrcode = new QRCode($optionen);
$bild = $qrcode->render('Kontaktdaten: Max Mustermann, info@beispiel.de');
file_put_contents(__DIR__ . '/kontakt-qr.png', $bild);
echo 'QR-Code mit hoher Fehlerkorrektur gespeichert.';
Die Stufe ECC_L korrigiert etwa 7% Fehler, ECC_M rund 15%, ECC_Q etwa 25% und ECC_H bis zu 30%. Höhere Korrekturstufen erzeugen größere QR-Codes, bieten jedoch mehr Robustheit gegenüber Beschädigungen. Bei sehr langen Texten steigt die Komplexität des QR-Codes, was die Lesbarkeit beeinträchtigen kann. Für die meisten Anwendungsfälle ist ECC_M ein guter Kompromiss zwischen Größe und Zuverlässigkeit.
QR-Code als SVG erzeugen
Neben PNG lassen sich QR-Codes auch im SVG-Format ausgeben. SVG-Dateien sind verlustfrei skalierbar und eignen sich besonders für den Einsatz auf Webseiten oder im Druck.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
$optionen = new QROptions([
'outputType' => QRCode::OUTPUT_MARKUP_SVG,
'svgViewBoxSize' => 0,
'eccLevel' => QRCode::ECC_M,
]);
$qrcode = new QRCode($optionen);
$svg = $qrcode->render('https://www.beispiel.de');
file_put_contents(__DIR__ . '/qrcode.svg', $svg);
echo 'SVG-QR-Code gespeichert.';
SVG-Dateien benötigen keine GD-Extension und lassen sich per CSS weiter gestalten.
Farben und Darstellung anpassen
Über die Optionen imageTransparent, bgColor und moduleValues lässt sich das Erscheinungsbild des QR-Codes anpassen.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
$optionen = new QROptions([
'outputType' => QRCode::OUTPUT_IMAGE_PNG,
'scale' => 10,
'eccLevel' => QRCode::ECC_M,
'imageTransparent' => false,
'bgColor' => [255, 255, 255],
'moduleValues' => [
1024 => [0, 51, 153], /* Dunkle Module: Dunkelblau */
6 => [0, 51, 153], /* Alignment-Pattern */
2 => [0, 51, 153], /* Finder-Pattern */
],
]);
$qrcode = new QRCode($optionen);
$qrcode->render('https://www.beispiel.de', __DIR__ . '/qrcode-blau.png');
echo 'Blauer QR-Code gespeichert.';
Die Farben werden als RGB-Array angegeben. So lassen sich QR-Codes an das Corporate Design anpassen.
Praxisbeispiele: vCard und WiFi
QR-Codes können weit mehr als URLs speichern. Mit speziellen Textformaten lassen sich Kontaktdaten als vCard oder WiFi-Zugangsdaten kodieren.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
/* vCard-QR-Code für Kontaktdaten */
$vcard = "BEGIN:VCARD\n"
. "VERSION:3.0\n"
. "FN:Max Mustermann\n"
. "ORG:Beispiel GmbH\n"
. "TEL:+49 170 1234567\n"
. "EMAIL:max@beispiel.de\n"
. "END:VCARD";
$optionen = new QROptions([
'outputType' => QRCode::OUTPUT_IMAGE_PNG,
'scale' => 10,
'eccLevel' => QRCode::ECC_M,
]);
$qrcode = new QRCode($optionen);
$qrcode->render($vcard, __DIR__ . '/kontakt.png');
/* WiFi-QR-Code für Netzwerkzugang */
$wifi = 'WIFI:T:WPA;S:MeinNetzwerk;P:GeheimesPasswort;;';
$qrcode->render($wifi, __DIR__ . '/wifi.png');
echo 'vCard- und WiFi-QR-Codes gespeichert.';
Das vCard-Format folgt dem Standard RFC 6350. Das WiFi-Format nutzt die Syntax WIFI:T:Verschluesselung;S:SSID;P:Passwort;;, wobei T den Verschlüsselungstyp angibt (WPA, WEP oder nopass).
Fehlerbehandlung
Bei ungültigen oder leeren Eingaben wirft die Bibliothek Exceptions. Eine saubere Fehlerbehandlung verhindert unerwartete Abstürze.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
function qrCodeErzeugen(string $daten, string $dateiPfad): bool
{
if (trim($daten) === '') {
echo 'Fehler: Leere Eingabedaten.';
return false;
}
try {
$optionen = new QROptions([
'outputType' => QRCode::OUTPUT_IMAGE_PNG,
'scale' => 10,
'eccLevel' => QRCode::ECC_M,
]);
$qrcode = new QRCode($optionen);
$qrcode->render($daten, $dateiPfad);
return true;
} catch (\Throwable $e) {
echo 'QR-Code-Fehler: ' . $e->getMessage();
return false;
}
}
$erfolg = qrCodeErzeugen('https://www.beispiel.de', __DIR__ . '/sicher.png');
if ($erfolg) {
echo 'QR-Code erfolgreich erstellt.';
}
Typische Fehlerquellen sind leere Strings, zu lange Eingabedaten (die Kapazität hängt vom ECC-Level ab) und fehlende Schreibrechte auf dem Zielverzeichnis. Die maximale Datenlänge liegt bei etwa 2953 Bytes für ECC_L und sinkt mit höherer Fehlerkorrektur.
Fazit
Die Bibliothek chillerlan/php-qrcode deckt alle gängigen Szenarien der QR-Code-Erzeugung ab. Neben einfachen URLs lassen sich vCard-Kontaktdaten, WiFi-Zugangsdaten und beliebige Texte kodieren. Die Ausgabe ist als PNG, SVG oder Data-URI möglich, und über QROptions lassen sich Farben, Größe und Fehlerkorrektur frei konfigurieren. Eine saubere Fehlerbehandlung mit try-catch schützt vor Laufzeitfehlern bei ungültigen Eingaben.