Eigene PHP Bildergalerie mit Zugriffsrechten
Eigene PHP Bildergalerie mit Zugriffsrechten – So habe ich es gebaut
Die Ausgangslage
Auf meiner Website niederastroth.de wollte ich Bilder in verschiedenen Galerien organisieren – aber nicht alle für jeden sichtbar. Manche Galerien sollen nur für bestimmte eingeladene Personen zugänglich sein, andere für alle Besucher. Gleichzeitig sollten Gäste die Bilder nur mit Wasserzeichen sehen, während eingeloggte User die Originale herunterladen können.
Fertige Lösungen wie WordPress-Plugins oder externe Dienste kamen nicht in Frage – die Seite läuft auf Mobirise und ich wollte die volle Kontrolle behalten.
Was die Galerie kann
Die technische Umsetzung
Datenbankstruktur
Als Datenbank kommt SQLite zum Einsatz – kein separater Datenbankserver nötig, die gesamte Datenbank liegt als einzelne Datei auf dem Server. Zwei Tabellen reichen aus:
-- Bilder
CREATE TABLE images (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
filename TEXT,
category TEXT DEFAULT 'standard',
status INTEGER DEFAULT 1,
sort_order INTEGER DEFAULT 0,
created_at DATETIME
);
-- Benutzer
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE,
password TEXT,
allowed_category TEXT DEFAULT 'standard',
is_admin INTEGER DEFAULT 0,
active INTEGER DEFAULT 1
);
Die allowed_category Spalte bei den Usern enthält kommagetrennte Kategorienamen – zum Beispiel standard, urlaub, hochzeit. So einfach lässt sich steuern wer was sehen darf.
Wasserzeichen mit PHP GD
Das Wasserzeichen wird serverseitig über PHP's GD-Bibliothek auf jedes Bild gekachelt – das Logo wiederholt sich über das gesamte Bild:
// Wasserzeichen nur für Gäste
if (!isset($_SESSION['gal_user_id']) && file_exists(WATERMARK_FILE)) {
$img = imagecreatefromjpeg($path);
$wm = imagecreatefrompng(WATERMARK_FILE);
$wm_w = imagesx($wm);
$wm_h = imagesy($wm);
// Kacheln über das gesamte Bild
for ($y = 0; $y < imagesy($img); $y += $wm_h + 100) {
for ($x = 0; $x < imagesx($img); $x += $wm_w + 100) {
imagecopy($img, $wm, $x, $y, 0, 0, $wm_w, $wm_h);
}
}
imagejpeg($img, null, 85);
}
Session-Management über Domains
Eine besondere Herausforderung war das Session-Management: Die Galerie läuft unter niederastroth.de/bildgalerie/, die Mobirise-Seite aber unter www.niederastroth.de/bildgal1/. PHP-Sessions sind standardmäßig domain-gebunden – mit einem kleinen Trick lässt sich das lösen:
// Cookie gilt für gesamte Domain inkl. Subdomains
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '.niederastroth.de', // Punkt davor = alle Subdomains
'secure' => false,
'httponly' => true,
'samesite' => 'Lax'
]);
session_start();
ZIP-Import für Massenimport
Statt 50 Bilder einzeln hochzuladen, kann man einfach ein ZIP hochladen. PHP's ZipArchive Klasse macht das elegant möglich:
$zip = new ZipArchive();
if ($zip->open($zip_tmp) === true) {
for ($i = 0; $i < $zip->numFiles; $i++) {
$name = $zip->getNameIndex($i);
// Mac-Dateien ignorieren
if (strpos($name, '__MACOSX') !== false) continue;
$ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
if (!in_array($ext, ['jpg','jpeg','png','webp'])) continue;
$data = $zip->getFromIndex($i);
file_put_contents(UPLOAD_DIR . $new_name, $data);
// In DB eintragen...
}
$zip->close();
}
Die Admin-Oberfläche
Die Admin-Oberfläche ist in vier Tabs aufgeteilt:
- Bilder – alle Bilder in einer Übersicht, sortierbar per Drag & Drop
- Upload – Einzelbilder oder ZIP hochladen, Kategorie und Titel-Präfix festlegen
- User – Benutzer verwalten, Passwörter ändern, Kategorien zuweisen, Registrierungen freischalten
- Einstellungen – Wasserzeichen-Logo austauschen
Einbindung in Mobirise
Da die Website mit Mobirise gebaut ist, wird die Galerie per PHP-Include eingebunden. Damit Mobirise die Datei als PHP behandelt, muss ein kleiner PHP-Block in den Seiteneigenschaften unter "Before HTML" stehen:
<?php
session_set_cookie_params([...]);
session_start();
?>
Der eigentliche Include-Befehl steht in einem HTML-Block:
<?php include '/var/www/vhosts/niederastroth.de/httpdocs/bildgalerie/gallery.php'; ?>
Login per Popup
Der Anmelde-Button öffnet ein kleines Popup-Fenster. Nach erfolgreichem Login schließt sich das Popup automatisch und die Hauptseite lädt neu – so bleiben Domain und Session konsistent und es gibt keine Konflikte:
function openLogin(e) {
e.preventDefault();
const popup = window.open(url, 'login_popup', 'width=420,height=560,...');
const timer = setInterval(function() {
if (popup && popup.closed) {
clearInterval(timer);
window.location.reload(); // Seite neu laden nach Login
}
}, 500);
}
Was ich gelernt habe
Das Projekt hat mich einiges gelehrt – vor allem über die Tücken von PHP-Sessions über verschiedene Domains und Subdomains. Was auf dem Papier simpel klingt ("Session lesen wo sie gesetzt wurde") kann in der Praxis zu stundenlangem Debugging führen wenn www.niederastroth.de und niederastroth.de als verschiedene Domains behandelt werden.
Außerdem: SQLite ist für solche überschaubaren Projekte absolut ausreichend und erspart die Konfiguration eines MySQL-Servers. Die gesamte Datenbank ist eine einzige Datei die man einfach sichern oder kopieren kann.
PHP SQLite Bildergalerie Mobirise Webentwicklung Session GD Library ZipArchive
Fazit
Eine eigene PHP-Bildergalerie mit Zugriffsrechten ist kein Hexenwerk – aber es steckt mehr drin als man zunächst denkt. Wer die volle Kontrolle über seine Bilder und Zugriffsrechte behalten möchte, ist mit einer eigenen Lösung gut beraten. Der Aufwand lohnt sich: kein Plugin-Chaos, keine externen Dienste, keine monatlichen Kosten – und alles genau so wie man es braucht.
Habt ihr Fragen zur Umsetzung? Schreibt es gerne in die Kommentare! 👇