MVC Architektur verstehen | Enjyn Gruppe
Hallo Welt
Hallo Welt
Original Lingva Deutsch
Übersetzung wird vorbereitet...
Dieser Vorgang kann bis zu 60 Sekunden dauern.
Diese Seite wird erstmalig übersetzt und dann für alle Besucher gespeichert.
0%
DE Zurück zu Deutsch
Übersetzung durch Lingva Translate

241 Dokumentationen verfügbar

Wissensdatenbank

MVC Architektur Erklärt

Zuletzt aktualisiert: 20.01.2026 um 11:25 Uhr

MVC Architektur verstehen

MVC trennt Anwendungslogik in drei Komponenten für bessere Wartbarkeit. Lernen Sie Model, View und Controller mit praktischen Beispielen.

Die drei Komponenten

┌─────────────────────────────────────────────────────────────┐
│                        MVC PATTERN                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│                    ┌──────────────┐                         │
│          ┌────────►│     VIEW     │◄───────┐                │
│          │         │  (Template)  │        │                │
│          │         └──────────────┘        │                │
│          │                                 │                │
│     Updates                          Reads Data             │
│          │                                 │                │
│          │                                 │                │
│   ┌──────┴───────┐               ┌────────┴──────┐         │
│   │   MODEL      │◄──────────────│  CONTROLLER   │         │
│   │  (Daten)     │   Updates     │   (Logik)     │         │
│   └──────────────┘               └───────┬───────┘         │
│                                          │                  │
│                                    User Input               │
│                                          │                  │
│                                    ┌─────┴─────┐           │
│                                    │   USER    │           │
│                                    └───────────┘           │
│                                                             │
└─────────────────────────────────────────────────────────────┘
Komponente Verantwortung Beispiele
Model Daten und Geschäftslogik User, Order, Product
View Darstellung/UI HTML Templates, JSON Output
Controller Eingabe-Verarbeitung, Koordination Request Handler, Route Handler

Einfaches PHP MVC Beispiel

// ========== MODEL ==========
// models/User.php

class User {
    public function __construct(
        public ?int $id = null,
        public string $name = '',
        public string $email = '',
        public string $createdAt = ''
    ) {}
}

class UserRepository {
    public function __construct(private PDO $db) {}

    public function findAll(): array {
        $stmt = $this->db->query('SELECT * FROM users ORDER BY created_at DESC');
        return array_map(
            fn($row) => new User($row['id'], $row['name'], $row['email'], $row['created_at']),
            $stmt->fetchAll(PDO::FETCH_ASSOC)
        );
    }

    public function find(int $id): ?User {
        $stmt = $this->db->prepare('SELECT * FROM users WHERE id = ?');
        $stmt->execute([$id]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        return $row ? new User($row['id'], $row['name'], $row['email'], $row['created_at']) : null;
    }

    public function save(User $user): void {
        if ($user->id === null) {
            $stmt = $this->db->prepare('INSERT INTO users (name, email) VALUES (?, ?)');
            $stmt->execute([$user->name, $user->email]);
            $user->id = (int) $this->db->lastInsertId();
        } else {
            $stmt = $this->db->prepare('UPDATE users SET name = ?, email = ? WHERE id = ?');
            $stmt->execute([$user->name, $user->email, $user->id]);
        }
    }

    public function delete(int $id): void {
        $stmt = $this->db->prepare('DELETE FROM users WHERE id = ?');
        $stmt->execute([$id]);
    }
}
// ========== VIEW ==========
// views/users/index.php

<!DOCTYPE html>
<html>
<head>
    <title>Benutzer</title>
</head>
<body>
    <h1>Benutzerliste</h1>

    <a href="/users/create">Neuer Benutzer</a>

    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Email</th>
                <th>Aktionen</th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($users as $user): ?>
            <tr>
                <td><?= htmlspecialchars($user->id) ?></td>
                <td><?= htmlspecialchars($user->name) ?></td>
                <td><?= htmlspecialchars($user->email) ?></td>
                <td>
                    <a href="/users/<?= $user->id ?>/edit">Bearbeiten</a>
                    <form action="/users/<?= $user->id ?>" method="POST" style="display:inline">
                        <input type="hidden" name="_method" value="DELETE">
                        <button type="submit">Löschen</button>
                    </form>
                </td>
            </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
</body>
</html>
// ========== CONTROLLER ==========
// controllers/UserController.php

class UserController {
    public function __construct(
        private UserRepository $userRepository,
        private View $view
    ) {}

    // GET /users
    public function index(): string {
        $users = $this->userRepository->findAll();

        return $this->view->render('users/index', [
            'users' => $users
        ]);
    }

    // GET /users/{id}
    public function show(int $id): string {
        $user = $this->userRepository->find($id);

        if (!$user) {
            throw new NotFoundException("User not found");
        }

        return $this->view->render('users/show', [
            'user' => $user
        ]);
    }

    // GET /users/create
    public function create(): string {
        return $this->view->render('users/create', [
            'user' => new User()
        ]);
    }

    // POST /users
    public function store(array $data): void {
        $user = new User(
            name: $data['name'],
            email: $data['email']
        );

        $this->userRepository->save($user);

        header('Location: /users');
        exit;
    }

    // GET /users/{id}/edit
    public function edit(int $id): string {
        $user = $this->userRepository->find($id);

        if (!$user) {
            throw new NotFoundException("User not found");
        }

        return $this->view->render('users/edit', [
            'user' => $user
        ]);
    }

    // PUT /users/{id}
    public function update(int $id, array $data): void {
        $user = $this->userRepository->find($id);

        if (!$user) {
            throw new NotFoundException("User not found");
        }

        $user->name = $data['name'];
        $user->email = $data['email'];

        $this->userRepository->save($user);

        header('Location: /users');
        exit;
    }

    // DELETE /users/{id}
    public function destroy(int $id): void {
        $this->userRepository->delete($id);

        header('Location: /users');
        exit;
    }
}

Router und Front Controller

// index.php - Front Controller
require 'vendor/autoload.php';

$router = new Router();

// Routes definieren
$router->get('/users', [UserController::class, 'index']);
$router->get('/users/create', [UserController::class, 'create']);
$router->get('/users/{id}', [UserController::class, 'show']);
$router->post('/users', [UserController::class, 'store']);
$router->get('/users/{id}/edit', [UserController::class, 'edit']);
$router->put('/users/{id}', [UserController::class, 'update']);
$router->delete('/users/{id}', [UserController::class, 'destroy']);

// Request verarbeiten
try {
    $response = $router->dispatch($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);
    echo $response;
} catch (NotFoundException $e) {
    http_response_code(404);
    echo "Nicht gefunden";
}

MVC Varianten

// MVP (Model-View-Presenter)
// View ist passiver, Presenter hat mehr Kontrolle

// MVVM (Model-View-ViewModel)
// Zwei-Wege-Datenbindung (Angular, Vue)

// MVC in REST APIs
class ApiUserController {
    // Gibt JSON statt HTML zurück
    public function index(): Response {
        $users = $this->userRepository->findAll();

        return new JsonResponse([
            'data' => array_map(fn($u) => $u->toArray(), $users)
        ]);
    }

    public function show(int $id): Response {
        $user = $this->userRepository->find($id);

        if (!$user) {
            return new JsonResponse(['error' => 'Not found'], 404);
        }

        return new JsonResponse(['data' => $user->toArray()]);
    }
}

JavaScript MVC (Vanilla)

// Model
class TodoModel {
    constructor() {
        this.todos = [];
        this.listeners = [];
    }

    addTodo(text) {
        this.todos.push({ id: Date.now(), text, completed: false });
        this.notify();
    }

    toggleTodo(id) {
        const todo = this.todos.find(t => t.id === id);
        if (todo) {
            todo.completed = !todo.completed;
            this.notify();
        }
    }

    deleteTodo(id) {
        this.todos = this.todos.filter(t => t.id !== id);
        this.notify();
    }

    subscribe(listener) {
        this.listeners.push(listener);
    }

    notify() {
        this.listeners.forEach(listener => listener(this.todos));
    }
}

// View
class TodoView {
    constructor(container) {
        this.container = container;
    }

    render(todos) {
        this.container.innerHTML = `
            
            
            
    ${todos.map(todo => `
  • ${todo.text}
  • `).join('')}
`; } bindAddTodo(handler) { this.container.querySelector('#addBtn').addEventListener('click', () => { const input = this.container.querySelector('#newTodo'); if (input.value.trim()) { handler(input.value); input.value = ''; } }); } bindToggleTodo(handler) { this.container.addEventListener('click', (e) => { if (e.target.classList.contains('toggle')) { const id = parseInt(e.target.closest('li').dataset.id); handler(id); } }); } bindDeleteTodo(handler) { this.container.addEventListener('click', (e) => { if (e.target.classList.contains('delete')) { const id = parseInt(e.target.closest('li').dataset.id); handler(id); } }); } } // Controller class TodoController { constructor(model, view) { this.model = model; this.view = view; // Model-Änderungen → View aktualisieren this.model.subscribe(todos => this.view.render(todos)); // View-Events → Model aktualisieren this.view.bindAddTodo(text => this.model.addTodo(text)); this.view.bindToggleTodo(id => this.model.toggleTodo(id)); this.view.bindDeleteTodo(id => this.model.deleteTodo(id)); // Initial rendern this.view.render(this.model.todos); } } // Initialisierung const app = new TodoController( new TodoModel(), new TodoView(document.getElementById('app')) );
💡 Best Practices: 1. Controller sollten dünn sein - Logik ins Model
2. Views sollten keine Geschäftslogik enthalten
3. Models sollten unabhängig von Views sein
4. Nutzen Sie Services für komplexe Geschäftslogik
5. Validierung kann im Model oder separater Klasse sein

Weitere Informationen

Enjix Beta

Enjyn AI Agent

Hallo 👋 Ich bin Enjix — wie kann ich dir helfen?
120