Datenbankanbindung und Models

Erste Schritte mit Datenbankanbindung und Models

In diesem Tutorial lernst du, wie du das phpFK – PHP Framework (oder ein vergleichbares MVC-System)
mit deiner Datenbank verbindest und die Verbindung in sogenannten Models nutzt.
Wir verwenden dabei PDO (PHP Data Objects) – eine standardisierte Schnittstelle,
die uns Sicherheit (Prepared Statements) und Flexibilität (verschiedene DB-Treiber) bietet.

Grundkonfiguration: config/database.php

Zunächst stellst du die Datenbankverbindung in der Datei config/database.php ein.
Dort findest du eine Art Array oder eine ähnliche Struktur, in der du Host, Datenbankname, Benutzername und
Passwort hinterlegst. Beispiel:

return [
    'DB_HOST' => 'localhost',
    'DB_NAME' => 'mein_projekt',
    'DB_USER' => 'root',
    'DB_PASS' => '',
    'DB_CHARSET' => 'utf8mb4',
];

Achte darauf, dass die Daten korrekt sind und deine MySQL/MariaDB (oder andere Datenbank) tatsächlich
unter diesen Zugangsdaten erreichbar ist. In vielen lokalen Umgebungen heißt der Datenbank-Benutzer einfach „root“
und das Passwort ist leer (XAMPP-Standard).

Model-Klasse erstellen

Ein Model ist für den Datenbankzugriff zuständig. In phpFK findest du meist eine Basisklasse
im Ordner core/Model.php, die sich schon um die Verbindung kümmert.
Du kannst daraus erben oder dir eine eigene Struktur aufbauen.
Hier eine beispielhafte Model-Klasse für eine „User“-Tabelle:

namespace App\Models;

use Core\Model;

class User extends Model
{
    protected $table = 'users';

    public function getAllUsers()
    {
        $sql = "SELECT * FROM " . $this->table;
        $stmt = $this->db->query($sql);
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }

    public function getUserById($id)
    {
        $sql = "SELECT * FROM " . $this->table . " WHERE id = :id";
        $stmt = $this->db->prepare($sql);
        $stmt->bindValue(':id', $id, \PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetch(\PDO::FETCH_ASSOC);
    }
}

1. Wir erweitern die Model-Klasse, die in core/Model.php eine Eigenschaft

$this->db

enthält, über die wir auf die PDO-Verbindung zugreifen können.
2.

getAllUsers()

holt alle Zeilen aus der Tabelle users.
3.

getUserById($id)

holt einen bestimmten Datensatz per Prepared Statement,
was vor SQL-Injections schützt.

Erweiterte Abfragen & Prepared Statements

Um Datensätze einzufügen, zu aktualisieren oder zu löschen, kannst du Prepared Statements verwenden.
Ein Beispiel fürs Einfügen:

public function createUser($username, $email)
{
    $sql = "INSERT INTO " . $this->table . " (username, email) VALUES (:user, :mail)";
    $stmt = $this->db->prepare($sql);
    $stmt->bindValue(':user', $username, \PDO::PARAM_STR);
    $stmt->bindValue(':mail', $email, \PDO::PARAM_STR);
    return $stmt->execute(); // true bei Erfolg
}

Damit stellst du sicher, dass die Eingaben korrekt gebunden werden, was insbesondere gegen SQL-Injection-Angriffe schützt.

Datenbankverbindung intern (core/Model.php)

Schauen wir uns ein vereinfachtes Beispiel an, wie core/Model.php
die PDO-Verbindung bereitstellen könnte:

namespace Core;

class Model
{
    protected $db;

    public function __construct()
    {
        // Konfigurationsarray laden
        $config = require CONFIG_PATH . 'database.php';

        $dsn = "mysql:host={$config['DB_HOST']};dbname={$config['DB_NAME']};charset={$config['DB_CHARSET']}";
        try {
            $this->db = new \PDO($dsn, $config['DB_USER'], $config['DB_PASS']);
            $this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
        } catch (\PDOException $e) {
            // Handle Error (Logging, Ausgabe)
            die("DB-Verbindung fehlgeschlagen: " . $e->getMessage());
        }
    }
}

1. $config liest die Verbindungsdaten aus database.php.
2. $this->db wird zum PDO-Objekt, auf das Kinderklassen (z. B. User) zugreifen.
3. Wir setzen PDO::ATTR_ERRMODE auf ERRMODE_EXCEPTION, um Fehler sauber abfangen zu können.

Verwendung im Controller

Wenn du jetzt in einem Controller auf die Datenbank zugreifen möchtest, erstellst du einfach eine
Instanz des entsprechenden Models und rufst dessen Methoden auf.
Beispielsweise so in app/controllers/UserController.php:

namespace App\Controllers;

use Core\Controller;
use App\Models\User;

class UserController extends Controller
{
    public function index()
    {
        $userModel = new User();
        $allUsers = $userModel->getAllUsers();

        // Vielleicht übergeben wir die Nutzerdaten an eine View:
        return \Core\View::render('user_list', ['users' => $allUsers]);
    }

    public function show($id)
    {
        $userModel = new User();
        $user = $userModel->getUserById($id);

        // Falls kein Eintrag gefunden wurde, kann man eine Fehlermeldung ausgeben
        if (!$user) {
            echo "Kein Nutzer mit ID $id gefunden.";
            return;
        }

        return \Core\View::render('user_detail', ['user' => $user]);
    }
}

Hier siehst du:

  • Wir instanzieren User, unser Model.
  • getAllUsers()

    oder

    getUserById()

    liefert die DB-Daten zurück.

  • Wir übergeben die Daten an eine passende View (user_list, user_detail).

Tipps & Tricks für saubere Datenbanknutzung

  • Prepared Statements: Immer
    prepare()

    und

    bindParam()

    (oder

    bindValue()

    ) nutzen, um SQL-Injection sicher zu verhindern.

  • Mehr Struktur mit Query-Buildern: Wenn dir nacktes PDO zu unübersichtlich ist, kannst du
    ein Query-Builder-Paket oder ORMs (z. B. Eloquent, Doctrine) integrieren.
  • Fehlerbehandlung: Stelle sicher, dass du Exceptions protokollierst (etwa in storage/logs/),
    um bei Problemen schnell die Ursachen zu finden.
  • Trennung von Logik und Anzeige: Halte deinen Controller schlank und schiebe Datenbanklogik
    konsequent in die Models. So bleibt dein Projekt übersichtlich.

Kurzes Beispiel einer SQL-Tabelle „users“

Wenn du lokal testen willst, leg dir doch diese kleine Beispieltabelle an:

CREATE TABLE `users` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(50) NOT NULL,
  `email` VARCHAR(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Danach kannst du über

INSERT

ein paar Testdaten anlegen und sehen,
wie User-Model und Controller sie dir im Browser ausgeben.

Fazit

Die Datenbankanbindung im phpFK – PHP Framework läuft über eine simple
config/database.php und eine Model-Basisklasse.
Durch PDO hast du alle Vorteile moderner PHP-Datenbankzugriffe, einschließlich
Prepared Statements und Unterstützung für verschiedene DB-Systeme (MySQL, PostgreSQL, SQLite etc.).
Das Model-Konzept hält deinen Code sauber, indem es die Datenbankoperationen von der Controller-Logik trennt.
So lassen sich auch komplexere Queries leicht realisieren, ohne dass du den Überblick verlierst.