Alle Funktionen stehen nach einem einzigen require zur Verfügung:
require_once __DIR__ . "/manage-client/lib/client.php";
Die Kommandozeile (bin/manage-client.php) und die Oberfläche (ui/panel.php)
enthalten keine eigene Logik, sondern rufen genau diese Funktionen auf. Eine
Funktion verhält sich deshalb identisch, egal wie sie ausgelöst wird.
Fehler werden als RuntimeException geworfen. Ausnahmen von dieser Regel sind
ausdrücklich vermerkt.
manageClientStatus(): arraySammelaufruf für Oberflächen. Wirft nie: Jeder Fehler landet im Rückgabewert, damit eine Einstellungsseite auch bei nicht erreichbarem Server rendert.
[
"instance" => "mein-projekt-prod",
"server_url" => "https://manage.example.org",
"configured" => true,
"version" => "v1.2.3", // "" wenn nicht ermittelbar
"php_version" => "8.3.6",
"update" => [...], // Rückgabe von manageUpdateCheck(), oder null
"update_error" => null, // Fehlermeldung, wenn die Prüfung scheiterte
"backups" => [...], // Rückgabe von manageBackupList()
"last_backup_at" => "2026-08-20T09:21:04+00:00",
"pending_migrations" => [...],
"errors" => [], // nicht-fatale Warnungen
]
manageClientVersion(): stringInstallierte Version, zum Beispiel "v1.2.3". Gibt "" zurück, wenn sie nicht
ermittelbar ist; das ist kein Fehler, sondern "unbekannt".
manageClientConfigured(): boolOb Server-URL, Instanz und Token gesetzt sind.
manageUpdateCheck(): arrayHolt das Manifest und vergleicht die Versionen.
[
"current" => "v1.2.3",
"latest" => "v1.3.0",
"available" => true,
"manifest" => [
"version" => "v1.3.0",
"package_url" => "https://…/api/v1/package.php?version=v1.3.0",
"sha256" => "…",
"size" => 421337,
"published_at" => "2026-08-20T09:20:43+00:00",
],
]
Ist die installierte Version unbekannt, gilt available => true, damit eine
Installation ohne lesbare Versionsdatei nicht dauerhaft blockiert.
manageUpdateApply(array $options = []): arrayLädt das Paket, prüft Größe und SHA-256, entpackt es, rollt es aus und führt anschließend den Post-Update-Schritt aus.
Optionen:
| Option | Bedeutung |
|---|---|
force |
Auch ausrollen, wenn keine neuere Version vorliegt |
skip_hook |
Nur Dateien ausrollen, weder Migrationen noch Callback ausführen |
Rückgabe:
[
"deployed" => true,
"from_version" => "v1.2.3",
"to_version" => "v1.3.0",
"copied" => 128,
"backed_up" => 126,
"skipped" => 2, // geschützte Pfade
"removed_backups" => 1,
"backup_dir" => "/…/data/manage/updates/20260820-092114-v1.3.0",
"hook" => [...], // siehe unten
]
Wirft, wenn das Ausrollen scheitert. Scheitert nur der Post-Update-Schritt,
kehrt die Funktion normal zurück und hook["success"] ist false – die Dateien
sind dann bereits ausgerollt. Aufrufer müssen beides unterscheiden; siehe
07_POST_UPDATE_HOOKS.
Wichtig: Das Ausrollen überschreibt Dateien im laufenden Betrieb. Es gibt keine
Wartungsseite und keine Rücknahme. Die überschriebenen Dateien liegen als Kopie in
backup_dir, aber ausschließlich für die manuelle Wiederherstellung.
manageUpdatePendingMigrations(): arrayNoch nicht ausgeführte Migrationen in Ausführungsreihenfolge:
[["id" => "2026-08-20-01-add-index", "path" => "/…/migrations/2026-08-20-01-add-index.php"]]
manageUpdateRunMigrations(array $context = []): arrayFührt die offenen Migrationen aus. Wirft nicht, sondern meldet:
[
"success" => false,
"applied" => ["2026-08-20-01-add-index"],
"failed" => "2026-08-20-02-backfill",
"error" => "SQLSTATE[42S22]: …",
"pending" => 2, // inklusive der fehlgeschlagenen
]
manageBackupCreate(string $trigger = "manual"): arrayErstellt ein lokales Archiv und lädt es hoch, sofern MANAGE_BACKUP_UPLOAD aktiv ist.
$trigger ist frei wählbar; üblich sind manual, automatic, cron, update.
Nur automatic und cron zählen für die Intervallprüfung.
[
"filename" => "backup-20260820-092104.zip",
"created_at" => "2026-08-20T09:21:04+00:00",
"trigger" => "cron",
"size" => 427,
"file_count" => 3,
"source_bytes" => 63,
"sha256" => "…",
"app_version" => "v1.2.3",
"database" => null, // oder ["tables" => 12, "rows" => 4711, …]
"remote_uploads" => [
["target" => "Manage-Server", "type" => "manage", "success" => true, …],
],
]
Ein fehlgeschlagener Upload macht das lokale Archiv nicht ungültig: Der Fehler
steht in remote_uploads[].error und im Protokoll, die Funktion wirft nicht. Wirft
sie doch, ist das Archiv selbst nicht zustande gekommen.
Gleichzeitige Läufe werden über eine Sperrdatei verhindert; der zweite Lauf wirft
sofort Es läuft bereits ein Backup.
manageBackupCreateAutomaticIfDue(): ?arrayErstellt ein Backup, wenn seit dem letzten automatischen Backup
MANAGE_BACKUP_AUTO_INTERVAL_SECONDS vergangen sind, sonst null. Für Hosting ohne
Cron gedacht; gehört auf eine selten geladene Adminseite.
manageBackupList(): arrayLokale Archive, neuestes zuerst. Selbstheilend: Einträge ohne Datei werden entfernt, Größen werden von der Festplatte aktualisiert.
manageBackupUpload(string $archivePath, array $meta = []): arrayLädt ein vorhandenes Archiv zum Manage-Server. Wird von manageBackupCreate()
automatisch aufgerufen und ist nur für Sonderfälle einzeln nötig – etwa um ein
Archiv nach einem Serverausfall nachzureichen.
manageBackupPath(string $filename): stringAbsoluter Pfad eines lokalen Archivs. Validiert den Dateinamen streng, damit ein Download-Formular keinen beliebigen Pfad ausliefern kann.
manageHeartbeatSend(): arrayMeldet Version, PHP-Version, freien Speicher, offene Migrationen und den Zeitpunkt des letzten Backups. Die Antwort enthält nebenbei die Update-Information:
["success" => true, "latest" => "v1.3.0", "update_available" => true, "server_time" => "…"]
manageHeartbeatSendQuietly(): ?arrayWie oben, wirft aber nie und gibt bei Fehlern null zurück. Für Aufrufe innerhalb
des Projekts, in denen ein nicht erreichbarer Server folgenlos bleiben soll.
| Funktion | Zweck |
|---|---|
manageFormatBytes(int $bytes): string |
1.234.567 → 1,18 MB |
manageClientLog(string $level, string $message, array $context = []): void |
Eine Zeile ins Client-Protokoll. Wirft nie |
manageRemoteCapabilities(): array |
Welche konfigurierten Zieltypen dieses System unterstützt |
require_once __DIR__ . "/manage-client/lib/client.php";
$check = manageUpdateCheck();
if ($check["available"]) {
manageBackupCreate("update"); // vor dem Update sichern
$result = manageUpdateApply();
if (!$result["hook"]["success"]) {
// Dateien sind ausgerollt, der Post-Update-Schritt nicht.
error_log("Migration fehlgeschlagen: " . $result["hook"]["error"]);
}
}
Ein Backup vor dem Update ist bewusst nicht eingebaut, sondern eine Zeile im Projekt – so bleibt sichtbar, dass es passiert.