Systemvoraussetzungen für das QR-Etiketten-System prüfen

Das QR-Etiketten-System wird als separate Kundeninstallation eingerichtet. Es benötigt kein WordPress, kein TYPO3, kein WooCommerce, kein Shopware und kein anderes CMS. Die Anwendung läuft eigenständig auf Basis von PHP und MySQL/MariaDB.

Damit die Installation der E-Label-Lösung für Wein, Sekt und aromatisierte Weinerzeugnisse vollständig funktioniert, sollte das Webhosting folgende Voraussetzungen erfüllen:

  • PHP 8.0 oder neuer
  • MySQL oder MariaDB
  • PHP-Erweiterung „mysqli“
  • PHP-Erweiterung „GD“ mit PNG-Unterstützung
  • aktivierte Datei-Uploads
  • Schreibrechte im Projektverzeichnis
  • ausreichende PHP-Limits für CSV-Importe
  • Möglichkeit zur Erstellung von ZIP-Dateien
  • HTTPS/SSL-Zertifikat für die öffentliche QR-Zieladresse
  • Hosting-seitiger Passwortschutz für den Administrationsbereich
  • Optional für GTIN/EAN-basierte URLs:
    Wenn die URL-Variante nach GS1-Digital-Link-Logik in der Form /qr-code-etiketten.php/01/04012345678901 genutzt werden soll, muss das Hosting zusätzliche Pfadinformationen hinter PHP-Dateien korrekt an PHP übergeben können (PATH_INFO). Falls ein Hosting dies nicht unterstützt, kann alternativ die Fallback-Variante mit Query-Parameter genutzt werden, zum Beispiel ?gtin=04012345678901.

Wichtig:

Das aktuelle QR-Etiketten-System enthält kein eigenes internes Login- oder Rollenmodell. Der Administrationsbereich sollte daher über das Webhosting geschützt werden, zum Beispiel per .htaccess/.htpasswd, über den Passwortschutz des Hostinganbieters oder über eine vergleichbare Zugriffsbeschränkung.

Die Daten werden in einer eigenen MySQL-/MariaDB-Projekttabelle gespeichert. Dabei ist es unerheblich, ob eine neue Datenbank oder eine bereits vorhandene Datenbank genutzt wird. Wichtig ist nur, dass für das QR-Etiketten-System ein eigener eindeutiger Tabellenname verwendet wird.

Für die ZIP-Erstellung der QR-Code-Grafiken wird im aktuellen Projektstand eine Serverfunktion verwendet, die das externe ZIP-Programm des Servers aufruft. Einige Hostinganbieter deaktivieren solche Funktionen aus Sicherheitsgründen. In diesem Fall kann die automatische ZIP-Erstellung eingeschränkt sein oder eine technische Anpassung nach Aufwand erforderlich werden.

Möglichkeiten zur Prüfung der Systemvoraussetzungen

1. Prüfung im Kundenmenü des Hostinganbieters

Viele Hostinganbieter zeigen die wichtigsten Werte direkt im Kundenmenü an. Prüfen Sie dort insbesondere:

  • verwendete PHP-Version
  • aktivierte PHP-Erweiterungen
  • MySQL- oder MariaDB-Datenbanken
  • Upload-Limits
  • Speicherlimit
  • maximale Script-Laufzeit
  • deaktivierte PHP-Funktionen
  • Möglichkeit zum Passwortschutz für Verzeichnisse

Teilweise können PHP-Versionen und PHP-Erweiterungen dort direkt geändert oder aktiviert werden.

2. Prüfung mit phpinfo()

Eine einfache Möglichkeit zur Prüfung ist die PHP-Funktion phpinfo().

Legen Sie dazu testweise eine Datei mit dem Namen phpinfo.php in den späteren Installationsordner des QR-Etiketten-Systems.

Inhalt der Datei:

<?php
phpinfo();
?>

Rufen Sie die Datei anschließend im Browser auf, zum Beispiel:

https://www.ihre-domain.de/phpinfo.php

Suchen Sie in der Ausgabe nach folgenden Begriffen:

  • PHP Version
  • mysqli
  • gd
  • PNG Support
  • file_uploads
  • upload_max_filesize
  • post_max_size
  • memory_limit
  • max_execution_time
  • disable_functions

Worauf Sie achten sollten:

PHP Version:

Hier sollte PHP 8.0 oder neuer angezeigt werden.

mysqli:
Es sollte ein eigener Abschnitt „mysqli“ vorhanden sein. Diese Erweiterung wird für die Datenbankverbindung benötigt.

gd:
Es sollte ein eigener Abschnitt „gd“ vorhanden sein. Diese Erweiterung wird für die QR-Code-Grafiken benötigt.

PNG Support:
Innerhalb der GD-Informationen sollte PNG-Unterstützung vorhanden sein.

file_uploads:
Der Wert sollte auf „On“ stehen. Das wird für den CSV-Import benötigt.

upload_max_filesize und post_max_size:
Diese Werte sollten groß genug für die zu importierenden CSV-Dateien sein.

memory_limit:
Für normale Produktlisten reicht häufig ein üblicher Wert wie 128 MB. Bei sehr großen CSV-Dateien kann ein höherer Wert sinnvoll sein.

max_execution_time:
Bei großen CSV-Importen kann eine längere Script-Laufzeit notwendig sein.

disable_functions:
Hier sollte geprüft werden, ob Funktionen wie exec deaktiviert sind. Wenn exec deaktiviert ist, kann die automatische ZIP-Erstellung der QR-Code-Grafiken im aktuellen Projektstand eingeschränkt sein.

Wichtig:

Die Datei phpinfo.php sollte nur kurzfristig zur Prüfung verwendet und anschließend sofort wieder gelöscht werden. Die Ausgabe enthält technische Serverinformationen, die nicht dauerhaft öffentlich abrufbar sein sollten.

3. Prüfung mit einem kleinen Systemcheck-Script

Zusätzlich kann ein kleines PHP-Systemcheck-Script verwendet werden. Dieses prüft wichtige Funktionen direkt im späteren Installationsordner.

Legen Sie dazu eine Datei mit folgendem Namen an:

systemcheck-qr-etiketten.php

Inhalt der Datei:

<?php
/**
 * Systemcheck für QR-Etiketten-System
 * Stand: 24.5.26
 *
 * Upload in den geplanten Installationsordner, im Browser aufrufen,
 * Ergebnis prüfen und diese Datei danach wieder löschen.
 */

declare(strict_types=1);

header('Content-Type: text/html; charset=UTF-8');

const QR_MIN_PHP_VERSION = '8.0.0';

function h(mixed $value): string
{
    return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

function bool_ini(string $key): bool
{
    return filter_var(ini_get($key), FILTER_VALIDATE_BOOLEAN);
}

function parse_size_to_bytes(string $value): int
{
    $value = trim($value);
    if ($value === '' || $value === '-1') {
        return -1;
    }

    $unit = strtolower(substr($value, -1));
    $number = (float)$value;

    switch ($unit) {
        case 'g': return (int)($number * 1024 * 1024 * 1024);
        case 'm': return (int)($number * 1024 * 1024);
        case 'k': return (int)($number * 1024);
        default:  return (int)$number;
    }
}

function format_bytes(int $bytes): string
{
    if ($bytes < 0) {
        return 'unbegrenzt / nicht begrenzt';
    }
    if ($bytes >= 1024 * 1024 * 1024) {
        return round($bytes / (1024 * 1024 * 1024), 2) . ' GB';
    }
    if ($bytes >= 1024 * 1024) {
        return round($bytes / (1024 * 1024), 2) . ' MB';
    }
    if ($bytes >= 1024) {
        return round($bytes / 1024, 2) . ' KB';
    }
    return $bytes . ' B';
}

function disabled_functions(): array
{
    $raw = (string)ini_get('disable_functions');
    if (trim($raw) === '') {
        return [];
    }
    return array_values(array_filter(array_map('trim', explode(',', $raw))));
}

function function_available(string $function): bool
{
    return function_exists($function) && !in_array($function, disabled_functions(), true);
}

function status_row(string $label, string $status, string $info = '', string $importance = 'pflicht'): array
{
    return [
        'label' => $label,
        'status' => $status,
        'info' => $info,
        'importance' => $importance,
    ];
}

function status_class(string $status): string
{
    return match ($status) {
        'OK' => 'ok',
        'WARNUNG' => 'warn',
        default => 'fail',
    };
}

function print_table(array $rows, string $title): void
{
    echo '<h2>' . h($title) . '</h2>';
    echo '<table>';
    echo '<thead><tr><th>Prüfung</th><th>Status</th><th>Hinweis</th><th>Art</th></tr></thead><tbody>';
    foreach ($rows as $row) {
        echo '<tr>';
        echo '<td>' . h($row['label']) . '</td>';
        echo '<td class="' . h(status_class($row['status'])) . '"><strong>' . h($row['status']) . '</strong></td>';
        echo '<td>' . h($row['info']) . '</td>';
        echo '<td>' . h($row['importance']) . '</td>';
        echo '</tr>';
    }
    echo '</tbody></table>';
}

function test_writable_dir(string $path): array
{
    $path = rtrim($path, DIRECTORY_SEPARATOR);
    $exists = is_dir($path);

    if (!$exists) {
        return ['WARNUNG', 'Ordner existiert noch nicht: ' . $path . ' – kann bei Installation angelegt werden, sofern Schreibrechte vorhanden sind.'];
    }

    if (!is_writable($path)) {
        return ['FEHLT', 'Ordner ist nicht beschreibbar: ' . $path];
    }

    $testFile = $path . DIRECTORY_SEPARATOR . 'qr-systemcheck-' . bin2hex(random_bytes(4)) . '.tmp';
    $ok = @file_put_contents($testFile, 'test') !== false;
    if ($ok && is_file($testFile)) {
        @unlink($testFile);
    }

    return $ok
        ? ['OK', 'Ordner ist beschreibbar: ' . $path]
        : ['FEHLT', 'Ordner ist vorhanden, aber Testdatei konnte nicht geschrieben werden: ' . $path];
}

function check_external_zip(): array
{
    if (!function_available('exec')) {
        return ['WARNUNG', 'exec() ist nicht verfügbar oder deaktiviert. Der ZIP-Download der QR-Code-Grafiken ist im aktuellen Projektstand dadurch wahrscheinlich eingeschränkt.'];
    }

    $output = [];
    $returnCode = 1;
    @exec('command -v zip 2>&1', $output, $returnCode);

    if ($returnCode === 0 && !empty($output)) {
        return ['OK', 'Externes zip-Programm gefunden: ' . implode(' ', $output)];
    }

    $output = [];
    $returnCode = 1;
    @exec('zip -v 2>&1', $output, $returnCode);

    if (!empty($output)) {
        return ['OK', 'Externes zip-Programm scheint ausführbar zu sein.'];
    }

    return ['WARNUNG', 'Externes zip-Programm wurde nicht gefunden oder konnte nicht ausgeführt werden. Der ZIP-Download kann eingeschränkt sein.'];
}

function check_db_from_post(): ?array
{
    if ($_SERVER['REQUEST_METHOD'] !== 'POST' || ($_POST['do_db_check'] ?? '') !== '1') {
        return null;
    }

    $host = trim((string)($_POST['db_host'] ?? ''));
    $name = trim((string)($_POST['db_name'] ?? ''));
    $user = trim((string)($_POST['db_user'] ?? ''));
    $pass = (string)($_POST['db_pass'] ?? '');

    $rows = [];

    if (!extension_loaded('mysqli')) {
        $rows[] = status_row('Datenbankverbindung', 'FEHLT', 'mysqli-Erweiterung fehlt.', 'pflicht');
        return $rows;
    }

    if ($host === '' || $name === '' || $user === '') {
        $rows[] = status_row('Datenbankverbindung', 'FEHLT', 'Bitte DB-Host, Datenbankname und DB-Benutzer ausfüllen.', 'pflicht');
        return $rows;
    }

    mysqli_report(MYSQLI_REPORT_OFF);
    $mysqli = @new mysqli($host, $user, $pass, $name);

    if ($mysqli->connect_errno) {
        $rows[] = status_row('Datenbankverbindung', 'FEHLT', 'Verbindung fehlgeschlagen: ' . $mysqli->connect_error, 'pflicht');
        return $rows;
    }

    $rows[] = status_row('Datenbankverbindung', 'OK', 'Verbindung zur Datenbank erfolgreich. Serverinfo: ' . $mysqli->server_info, 'pflicht');

    if (!$mysqli->set_charset('utf8mb4')) {
        $rows[] = status_row('UTF-8/utf8mb4 Zeichensatz', 'WARNUNG', 'utf8mb4 konnte nicht gesetzt werden: ' . $mysqli->error, 'empfohlen');
    } else {
        $rows[] = status_row('UTF-8/utf8mb4 Zeichensatz', 'OK', 'utf8mb4 konnte gesetzt werden.', 'empfohlen');
    }

    $rows[] = status_row('DB-Schreibrechte', 'WARNUNG', 'Nicht geprüft. Es wurde bewusst keine Testtabelle angelegt oder verändert. Für die Installation muss der Datenbankbenutzer die benötigten Rechte besitzen.', 'hinweis');

    $mysqli->close();
    return $rows;
}

$rows = [];

$phpOk = version_compare(PHP_VERSION, QR_MIN_PHP_VERSION, '>=');
$rows[] = status_row('PHP-Version mindestens ' . QR_MIN_PHP_VERSION, $phpOk ? 'OK' : 'FEHLT', 'Aktuelle Version: ' . PHP_VERSION, 'pflicht');

$rows[] = status_row('mysqli-Erweiterung', extension_loaded('mysqli') ? 'OK' : 'FEHLT', extension_loaded('mysqli') ? 'mysqli ist geladen.' : 'mysqli fehlt. Datenbankzugriff nicht möglich.', 'pflicht');
$rows[] = status_row('GD-Erweiterung', extension_loaded('gd') ? 'OK' : 'FEHLT', extension_loaded('gd') ? 'GD ist geladen.' : 'GD fehlt. QR-PNG-Erzeugung nicht möglich.', 'pflicht');
$rows[] = status_row('PNG-Erzeugung imagepng()', function_exists('imagepng') ? 'OK' : 'FEHLT', function_exists('imagepng') ? 'imagepng() ist verfügbar.' : 'imagepng() fehlt. PNG-Ausgabe nicht möglich.', 'pflicht');
$rows[] = status_row('imagecreatetruecolor()', function_exists('imagecreatetruecolor') ? 'OK' : 'FEHLT', function_exists('imagecreatetruecolor') ? 'Funktion ist verfügbar.' : 'Funktion fehlt. QR-Bildgenerierung nicht möglich.', 'pflicht');
$rows[] = status_row('Datei-Uploads file_uploads', bool_ini('file_uploads') ? 'OK' : 'FEHLT', 'file_uploads = ' . ini_get('file_uploads'), 'pflicht für CSV-Import');

$memoryBytes = parse_size_to_bytes((string)ini_get('memory_limit'));
$rows[] = status_row('memory_limit', ($memoryBytes === -1 || $memoryBytes >= 128 * 1024 * 1024) ? 'OK' : 'WARNUNG', ini_get('memory_limit') . ' (' . format_bytes($memoryBytes) . ') – empfohlen: mindestens 128 MB.', 'empfohlen');

$uploadBytes = parse_size_to_bytes((string)ini_get('upload_max_filesize'));
$postBytes = parse_size_to_bytes((string)ini_get('post_max_size'));
$rows[] = status_row('upload_max_filesize', ($uploadBytes === -1 || $uploadBytes >= 2 * 1024 * 1024) ? 'OK' : 'WARNUNG', ini_get('upload_max_filesize') . ' (' . format_bytes($uploadBytes) . ')', 'empfohlen');
$rows[] = status_row('post_max_size', ($postBytes === -1 || $postBytes >= 2 * 1024 * 1024) ? 'OK' : 'WARNUNG', ini_get('post_max_size') . ' (' . format_bytes($postBytes) . ')', 'empfohlen');

$maxExecution = (int)ini_get('max_execution_time');
$rows[] = status_row('max_execution_time', ($maxExecution === 0 || $maxExecution >= 30) ? 'OK' : 'WARNUNG', $maxExecution === 0 ? '0 = unbegrenzt' : $maxExecution . ' Sekunden – empfohlen: mindestens 30 Sekunden, bei großen CSV-Dateien mehr.', 'empfohlen');

$rows[] = status_row('HTTPS aktiv', (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'OK' : 'WARNUNG', (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'Aufruf erfolgt per HTTPS.' : 'Aktueller Aufruf erfolgt nicht per HTTPS. Für öffentliche QR-Zielseiten empfohlen.', 'empfohlen');

$zipCheck = check_external_zip();
$rows[] = status_row('ZIP-Erstellung über externes zip', $zipCheck[0], $zipCheck[1], 'pflicht für ZIP-Download');

$disabled = disabled_functions();
$rows[] = status_row('Deaktivierte PHP-Funktionen', empty($disabled) ? 'OK' : 'WARNUNG', empty($disabled) ? 'Keine deaktivierten Funktionen laut disable_functions.' : implode(', ', $disabled), 'info');

$openBasedir = (string)ini_get('open_basedir');
$rows[] = status_row('open_basedir', trim($openBasedir) === '' ? 'OK' : 'WARNUNG', trim($openBasedir) === '' ? 'Nicht gesetzt.' : $openBasedir, 'info');

$dirRows = [];
$dirRows[] = status_row('Aktueller Ordner', ...test_writable_dir(__DIR__), importance: 'pflicht');
$expectedDirs = [
    __DIR__ . '/qr-codes',
    __DIR__ . '/qr-code-etiketten/csv-file',
    __DIR__ . '/qr-code-etiketten/sql-dumps',
];
foreach ($expectedDirs as $dir) {
    [$status, $info] = test_writable_dir($dir);
    $dirRows[] = status_row($dir, $status, $info, 'pflicht nach Installation');
}

$dbRows = check_db_from_post();

$criticalFailed = array_filter($rows, static fn($row) => $row['importance'] === 'pflicht' && $row['status'] === 'FEHLT');
$dirCriticalFailed = array_filter($dirRows, static fn($row) => $row['importance'] === 'pflicht' && $row['status'] === 'FEHLT');
$basicOk = empty($criticalFailed) && empty($dirCriticalFailed);

?><!doctype html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Systemcheck QR-Etiketten</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.5; margin: 24px; color: #222; }
        .box { border: 1px solid #ccc; border-radius: 8px; padding: 16px; margin: 16px 0; background: #fafafa; }
        .summary-ok { border-color: #11833b; background: #effaf2; }
        .summary-warn { border-color: #b26a00; background: #fff8e8; }
        table { border-collapse: collapse; width: 100%; margin: 12px 0 28px; }
        th, td { border: 1px solid #ccc; padding: 8px; vertical-align: top; text-align: left; }
        th { background: #eee; }
        .ok { color: #11833b; }
        .warn { color: #b26a00; }
        .fail { color: #b00020; }
        label { display: block; margin: 10px 0 4px; font-weight: bold; }
        input[type="text"], input[type="password"] { width: 100%; max-width: 560px; padding: 7px; box-sizing: border-box; }
        button { padding: 9px 14px; margin-top: 12px; cursor: pointer; }
        code { background: #eee; padding: 1px 4px; border-radius: 3px; }
    </style>
</head>
<body>
    <h1>Systemcheck QR-Etiketten</h1>

    <div class="box <?php echo $basicOk ? 'summary-ok' : 'summary-warn'; ?>">
        <h2>Gesamtbewertung</h2>
        <?php if ($basicOk): ?>
            <p><strong>Die wichtigsten Mindestvoraussetzungen für die Grundfunktionen sind erfüllt.</strong></p>
        <?php else: ?>
            <p><strong>Einige Mindestvoraussetzungen fehlen oder konnten nicht bestätigt werden.</strong></p>
        <?php endif; ?>
        <p>Diese Prüfung bezieht sich auf den aktuellen Stand des QR-Etiketten-Systems als eigenständige PHP-/MySQL-Anwendung.</p>
        <p><strong>Wichtig:</strong> Diese Datei nach der Prüfung wieder vom Server löschen.</p>
    </div>

    <?php print_table($rows, 'PHP- und Serverfunktionen'); ?>
    <?php print_table($dirRows, 'Dateiablage und Schreibrechte'); ?>

    <h2>Optionaler Datenbanktest</h2>
    <div class="box">
        <p>Hier kann zusätzlich geprüft werden, ob die MySQL-/MariaDB-Datenbank erreichbar ist. Die Zugangsdaten werden nicht gespeichert. Es wird keine Testtabelle angelegt und es werden keine Daten in der Datenbank verändert.</p>
        <form method="post">
            <input type="hidden" name="do_db_check" value="1">
            <label for="db_host">DB-Host</label>
            <input type="text" id="db_host" name="db_host" value="<?php echo h($_POST['db_host'] ?? 'localhost'); ?>">

            <label for="db_name">Datenbankname</label>
            <input type="text" id="db_name" name="db_name" value="<?php echo h($_POST['db_name'] ?? ''); ?>">

            <label for="db_user">DB-Benutzer</label>
            <input type="text" id="db_user" name="db_user" value="<?php echo h($_POST['db_user'] ?? ''); ?>">

            <label for="db_pass">DB-Passwort</label>
            <input type="password" id="db_pass" name="db_pass" value="">

            <button type="submit">Datenbank testen</button>
        </form>
    </div>

    <?php if ($dbRows !== null): ?>
        <?php print_table($dbRows, 'Ergebnis Datenbanktest'); ?>
    <?php endif; ?>

    <h2>Hinweise zur Bewertung</h2>
    <ul>
        <li><strong>Pflicht</strong>: Wird für die Grundfunktionen benötigt.</li>
        <li><strong>Pflicht für ZIP-Download</strong>: Wird für den ZIP-Download aller QR-Code-Grafiken benötigt. Die QR-Zielseiten und einzelne QR-PNGs können je nach Installation trotzdem funktionieren.</li>
        <li><strong>Empfohlen</strong>: Sollte für einen stabilen Betrieb vorhanden oder ausreichend hoch eingestellt sein.</li>
        <li><strong>Nach Installation</strong>: Diese Ordner müssen spätestens nach der Installation vorhanden und beschreibbar sein.</li>
        <li><strong>Datenbanktest</strong>: Prüft nur die Verbindung und den Zeichensatz. Es wird keine Tabelle erstellt, beschrieben oder gelöscht.</li>
    </ul>

    <p>Geplanter Einsatz: PHP 8+, MySQL/MariaDB, mysqli, GD/PNG, Datei-Uploads, Schreibrechte, CSV-Import, SQL-Dump, QR-PNG-Erzeugung und ZIP-Download der QR-Grafiken soweit serverseitig unterstützt.</p>
</body>
</html>

4. Prüfung per SSH, falls vorhanden

Falls Ihr Hostinganbieter SSH-Zugang anbietet, können einige Voraussetzungen auch über die Kommandozeile geprüft werden:

php -v

php -m

php -m | grep -i mysqli

php -m | grep -i gd

php -r 'echo function_exists("exec") ? "exec verfügbar" : "exec nicht verfügbar";'

php -i | grep -E "file_uploads|upload_max_filesize|post_max_size|memory_limit|max_execution_time|disable_functions"

command -v zip

zip -v

Nicht jedes Webhosting bietet SSH-Zugang an. Für die normale Installation ist SSH nicht zwingend erforderlich, kann die Prüfung aber erleichtern.

5. Prüfung durch den Hostinganbieter

Falls Sie unsicher sind, können Sie Ihrem Hostinganbieter folgende Frage stellen:

„Unser Dienstleister möchte eine kleine eigenständige PHP-/MySQL-Anwendung installieren. Benötigt werden PHP 8.0 oder neuer, MySQL oder MariaDB, mysqli, GD mit PNG-Unterstützung, Datei-Uploads, Schreibrechte im Projektverzeichnis und – für den ZIP-Download der QR-Code-Grafiken – die Möglichkeit, ein externes ZIP-Programm serverseitig aus PHP heraus aufzurufen. Außerdem soll der Administrationsordner per Passwortschutz geschützt werden können. Sind diese Voraussetzungen in meinem Hostingpaket gegeben?“

Zusammenfassung

Für die Installation der E-Label-Lösung für Wein, Sekt und aromatisierte Weinerzeugnisse des QR-Etiketten-Systems sind vor allem PHP 8.0 oder neuer, MySQL/MariaDB, mysqli, GD/PNG, Datei-Uploads und Schreibrechte wichtig. Für den ZIP-Download aller QR-Code-Grafiken muss zusätzlich die serverseitige ZIP-Erstellung möglich sein.

Falls einzelne Voraussetzungen nicht erfüllt sind, kann der Hostinganbieter diese teilweise aktivieren oder anpassen. Andernfalls kann eine technische Anpassung des Projekts nach Aufwand erforderlich werden.

Wichtig:

Die Dateien phpinfo.php und systemcheck-qr-etiketten.php sollten nach der Prüfung wieder gelöscht werden.

Loading

Kontakt zu uns