PHP Spickzettel
Wenn Sie alle paar Jahre PHP schreiben, vergessen Sie leicht die Syntax. In diesem Fall können Sie diesen Spickzettel nutzen. Dabei nutze ich Vergleiche mit JavaScript, um den Übergang zu erleichtern.
PHP Basics:
- Windows Setup
- php.ini
- phpMyAdmin in Windows ausführen
- Datenbank Verbindung
- Tabelle auslesen
- Tabelleneinträge
- Ausgabe mit echo
- Variablen
- Kommentare
- Style Guide
- Script Platzierung
- var_dump() – Wert und Datentyp ausgeben
- Arithmetische Operatoren
- String concatenation
- Standardfunktionen
- Nesting
- Integer
- Variablen und Konstanten
- Mathematische Zuweisungsoperatoren
- PHP-Variablen an JavaScript übergeben
- Conditional Statements:
if - If … Else
- if … elseif … else
- Switch
- Vergleichsoperatoren
- Logische Operatoren
- „Truthy“ & „falsy“ assignment
- Ternary Operator
- Zufallszahlen
- Funktionen
- Klassen
- Array
- Foreach
- For Schleife
- GET
- POST
- SSL Proxy
Laravel:
- Hilfreiche Links
- Laravel Installation
- Laravel Projekt anlegen
- Projekt bearbeiten
- Glossar
- Ordner und Dateien Übersicht
- Routes
- Views
- Layout Page
- Test Commands
- Production Builld
Windows Setup
Start → IIS eintippen → Internetinformationsdienste (IIS)-Manager
Wenn Sie den Webserver installiert haben, können Sie normalerweise lokal über http://localhost/ oder über http://127.0.0.1/ darauf zugreifen. Die URL lautet dann wie folgt:
http://localhost/php_test/index.php
php geht nicht, muss php_test heissen, php ist reserviert


%SystemDrive%\inetpub\wwwroot
D:\Users\denis\php_projekte\inetpub\wwwroot
To change the physical path of your IIS Web Code Module from C:\inetpub\wwwroot\php\ to D:\inetpub\wwwroot\php\, you can follow these steps:
- Open Internet Information Services (IIS) Manager:
- Press Win + R, type inetmgr and press Enter, or
- Go to Control Panel > Administrative Tools > Internet Information Services (IIS) Manager
- In the left panel (Connections pane), navigate to your website:
- Expand the server name
- Expand „Sites“
- Select your website (likely „Default Web Site“)
- Find your PHP application:
- Look for the virtual directory or application with the path /php/
- Select it
- Change the physical path:
- In the right-hand Actions pane, click „Basic Settings“ or double-click on „Basic Settings“ in the central Features View
- In the dialog that appears, change the physical path from C:\inetpub\wwwroot\ to D:\inetpub\wwwroot\
- Click „OK“ to save changes
- Make sure the new directory exists:
- Ensure D:\inetpub\wwwroot\ exists and contains all your PHP files
- If not, create it and copy your files from the C drive location
- Verify permissions:
- Ensure the IIS application pool identity has read and execute permissions on the new folder
- Right-click on the folder, select Properties > Security tab, and check permissions
- Test your site by navigating to http://localhost:80/php_test/ to make sure it works with the new path.
ACHTUNG: der Unterordner sollte php_test sein, nicht php (reserved word).
Modulzuordnung hinzufügen:

MIME Typ hinzufügen

http://localhost/php_test/index.php

php.ini
Enthält die Konfiguration. Ist unter C:\php zu finden.
phpMyAdmin in Windows ausführen
D:\Program Files (x86)\phpMyAdmin-5.2.2
config.sample.inc.php kopieren und in config.inc.php umbennen
Rechtsklick auf den Ordner und in „Terminal öffnen“ auswählen.

Oder direkt im Terminal eingeben:
cd /d "D:\Program Files (x86)\phpMyAdmin-5.2.2"
Webserver starten:
php -S 127.0.0.1:8001

Beide Befehle verkettet:
cd /d "D:\Program Files (x86)\phpMyAdmin-5.2.2" && php -S 127.0.0.1:8001
Dann diese URL ausführen:
Mit dem in MySQL definierten User und Password einloggen:

Datenbank Verbindung
<?php
if ($db = mysqli_connect("localhost", "dbuser", "h0inUP8Pi4uzLy9B2UWZk!", "myapp_testdb")) {
echo "Connection successful.";
mysqli_close($db);
} else {
echo "Error!";
}
?>
Mit config.php Datei. Die Datei wird mit Berechtigungen 640 abgelegt.

<?php
// ** MySQL-Einstellungen ** //
/**
* Ersetze datenbankname_hier_einfuegen mit dem Namen der Datenbank, die du verwenden möchtest.
*/
define( 'DB_NAME', 'myapp_testdb' );
/**
* Ersetze benutzername_hier_einfuegen mit deinem MySQL-Datenbank-Benutzernamen.
*/
define( 'DB_USER', 'ma_read' );
/**
* Ersetze passwort_hier_einfuegen mit deinem MySQL-Passwort.
*/
define( 'DB_PASSWORD', 'TVho7MVWB...' );
/**
* Ersetze localhost mit der MySQL-Serveradresse.
*/
define( 'DB_HOST', 'localhost' );
// es bleibt localhost auf der webseite
/**
* Der Datenbankzeichensatz, der beim Erstellen der Datenbanktabellen verwendet werden soll
*/
define( 'DB_CHARSET', 'utf8' );
Für Dateien, die ausschließlich PHP-Code enthalten (z.B. config.php), ist es tatsächlich eine empfohlene Praxis, das schließende ?>-Tag wegzulassen.
In der Verbindung aufrufen:
<?php
require_once __DIR__ . '/config.php';
// oder require_once __DIR__ . '/../config.php'; - wenn die config Datei im Verzeichnis darüber liegt
if ($db = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)) {
echo "Connection successful.";
mysqli_close($db);
} else {
echo "Error!";
}
?>
file_exists() prüft zuerst das aktuelle Verzeichnis — wird die Datei dort nicht gefunden, wird die eine Ebene darüber geladen.
<?php
$config = file_exists(__DIR__ . '/config.php')
? __DIR__ . '/config.php'
: __DIR__ . '/../config.php';
require_once $config;
if ($db = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)) {
echo "Connection successful.";
mysqli_close($db);
} else {
echo "Error!";
}
?>
Tabelle auslesen
- HTTP_ACCEPT_LANGUAGE wird ausgelesen (z.B. de-DE,de;q=0.9,en;q=0.8)
- Die ersten 2 Zeichen werden als lang_code verwendet (de)
- Prepared Statement sucht
greeting+ erkannter Sprache in der Tabellemessages - Kein Treffer → Fallback auf en
Inhalt von db_connect.php:
<?php
require_once __DIR__ . '/config.php';
$db = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if (!$db) {
die("Verbindungsfehler: " . mysqli_connect_error());
}
Ausgabelogik:
<?php
require_once __DIR__ . '/db_connect.php';
// Browser-Sprache auslesen und auf 2 Zeichen kürzen
$raw = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'en';
$lang = substr($raw, 0, 2);
// Greeting für erkannte Sprache laden
$stmt = mysqli_prepare($db, "SELECT content FROM messages WHERE text_key = 'greeting' AND lang_code = ?");
mysqli_stmt_bind_param($stmt, 's', $lang);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $content);
if (!mysqli_stmt_fetch($stmt)) {
// Fallback auf Englisch
mysqli_stmt_close($stmt);
$stmt = mysqli_prepare($db, "SELECT content FROM messages WHERE text_key = 'greeting' AND lang_code = 'en'");
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $content);
mysqli_stmt_fetch($stmt);
$lang = 'en (fallback)';
}
mysqli_stmt_close($stmt);
mysqli_close($db);
?>
<!DOCTYPE html>
<html lang="<?= htmlspecialchars(substr($lang, 0, 2)) ?>">
<head>
<meta charset="UTF-8">
<title>Greeting</title>
</head>
<body>
<p><strong>Browser-Sprache:</strong> <?= htmlspecialchars($raw) ?></p>
<p><strong>Erkannter lang_code:</strong> <?= htmlspecialchars($lang) ?></p>
<p><strong>Greeting:</strong> <?= htmlspecialchars($content ?? 'Welcome!') ?></p>
</body>
</html>
Texte pro Sprache und Page (z.B. Home) laden, im Array verarbeiten. PDO wird für FETCH_KEY_PAIR verwendet
db_connect_pdo.php
<?php
require_once __DIR__ . '/config.php';
$dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, DB_USER, DB_PASSWORD, $options);
} catch (\PDOException $e) {
die("Verbindungsfehler: " . $e->getMessage());
}
home.php
<?php
require_once __DIR__ . '/db_connect_pdo.php';
$page = 'home';
$raw = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'en';
$lang = substr($raw, 0, 2);
// Eine Abfrage holt ALLE Texte für Sprache + Seite
$stmt = $pdo->prepare("SELECT text_key, content FROM messages WHERE lang_code = :lang AND page = :page");
$stmt->execute(['lang' => $lang, 'page' => $page]);
// FETCH_KEY_PAIR → ['greeting' => 'Hallo', 'login_btn' => 'Anmelden', ...]
$texts = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
// Fallback auf Englisch, falls Sprache nicht vorhanden
if (empty($texts)) {
$stmt->execute(['lang' => 'en', 'page' => $page]);
$texts = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$lang = 'en (fallback)';
}
?>
<!DOCTYPE html>
<html lang="<?= htmlspecialchars(substr($lang, 0, 2)) ?>">
<head>
<meta charset="UTF-8">
<title>Greeting (optimiert)</title>
</head>
<body>
<p><strong>Browser-Sprache:</strong> <?= htmlspecialchars($raw) ?></p>
<p><strong>Erkannter lang_code:</strong> <?= htmlspecialchars($lang) ?></p>
<p><strong>Greeting:</strong> <?= htmlspecialchars($texts['greeting'] ?? 'Welcome!') ?></p>
<button><?= htmlspecialchars($texts['login_btn'] ?? 'Login') ?></button>
</body>
</html>
Tabelleneinträge
Gästebuch Beispiel. Separater Benutzer zum Schreiben, table-specific, hat SELECT und INSERT Berechtigungen nur für die gaestebuch Tabelle.
- Prepared Statement mit
?-Platzhaltern undbind_param('ss', ...)verhindert SQL-Injection. htmlspecialchars()beim Ausgeben verhindert, dass eingegebenes HTML/JS im Browser ausgeführt wird (XSS-Schutz).- POST statt
GETfür schreibende Aktionen — Daten landen nicht in der URL.
<?php
require_once __DIR__ . '/config.php';
$db = mysqli_connect(DB_HOST, DB_GUESTBOOK_USER, DB_GUESTBOOK_PASSWORD, DB_NAME);
if (!$db) {
die("Verbindungsfehler: " . mysqli_connect_error());
}
$gespeichert = isset($_GET['gespeichert']);
// Schreiben: nur wenn das Formular per POST abgeschickt wurde
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$nachricht = trim($_POST['nachricht'] ?? '');
if ($name !== '' && $nachricht !== '') {
// Prepared Statement schützt vor SQL-Injection
$stmt = mysqli_prepare($db, "INSERT INTO gaestebuch (name, nachricht) VALUES (?, ?)");
mysqli_stmt_bind_param($stmt, 'ss', $name, $nachricht);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
mysqli_close($db);
// Post/Redirect/Get: Weiterleitung verhindert doppeltes Absenden beim Aktualisieren
header('Location: ' . $_SERVER['PHP_SELF'] . '?gespeichert=1');
exit;
}
}
// Lesen: alle Einträge, neueste zuerst (nur im GET-Pfad erreicht)
$result = mysqli_query($db, "SELECT name, nachricht, erstellt_am FROM gaestebuch ORDER BY erstellt_am DESC");
$eintraege = mysqli_fetch_all($result, MYSQLI_ASSOC);
mysqli_close($db);
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gästebuch: Daten in die Datenbank schreiben</title>
</head>
<body>
<h1>Gästebuch: Daten in die Datenbank schreiben</h1>
<h2>Formular</h2>
<form method="post">
<p>
<label>Name:<br>
<input type="text" name="name" maxlength="50" required>
</label>
</p>
<p>
<label>Nachricht:<br>
<textarea name="nachricht" rows="4" cols="40" required></textarea>
</label>
</p>
<p>
<button type="submit">Eintragen</button>
</p>
</form>
<?php if ($gespeichert): ?>
<p><strong>Eintrag gespeichert.</strong></p>
<?php endif; ?>
<hr>
<h2>Bisherige Einträge</h2>
<?php if (empty($eintraege)): ?>
<p>Noch keine Einträge vorhanden.</p>
<?php else: ?>
<?php foreach ($eintraege as $eintrag): ?>
<p>
<strong><?= htmlspecialchars($eintrag['name']) ?></strong>
<em>(<?= htmlspecialchars($eintrag['erstellt_am']) ?>)</em><br>
<?= nl2br(htmlspecialchars($eintrag['nachricht'])) ?>
</p>
<?php endforeach; ?>
<?php endif; ?>
<hr>
</body>
</html>
Ausgabe mit echo
Die Anweisung echo kann mit oder ohne Klammern verwendet werden: echo oder echo().
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php
echo "<p>Hello World</p>";
?>
</body>
</html>
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php
echo("<p>Hello World</p>");
?>
</body>
</html>
<?php
// Basic PHP Hello World script
$greeting = "Hello, World!";
?>
<h1><?php echo $greeting; ?></h1>
Variablen
Variablen werdem mit $ definiert.
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php
$name = "Denis"; // Variable
/*
Block comment - Multiple lines
*/
echo "<h1>Heading</h1>";
echo "<p>Hello $name !</p>";
?>
</body>
</html>
Kommentare
Wie in JavaScript
// Comment line
/*
Block comment - Multiple lines
*/
Style Guide
Variablen werden immer klein geschrieben, mit Unterstrichen zwischen mehreren Wörtern (snake_case). Variablen fangen immer mit einem $ an.
$student_name = "Alice";
Konstanten verwenden nur Großbuchstaben.Wörter werden mit Unterstrichen getrennt.
define('MAX_RETRIES', 5);
Funktionen verwenden camelCase. Das erste Wort klein, danach jedes neue Wort groß.
function calculateTotalPrice() {
return 99;
}
Bei Klassen wird jedes Wort großschreiben, keine Unterstriche (PascalCase).
class StudentProfile {
// ...
}
Script Platzierung
<?php
// Bindet Header als PHP-Include ein
require_once 'includes/header.php';
?>
Für Dateien, die ausschließlich PHP-Code enthalten (z.B. config.php), ist es tatsächlich eine empfohlene Praxis, das schließende ?>-Tag wegzulassen.
Mit Variablen:
<?php
// Basic PHP Hello World script
$greeting = "Hello, World!";
$currentTime = date("Y-m-d H:i:s");
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PHP Hello World</title>
</head>
<body>
<h1><?php echo $greeting; ?></h1>
<p>This is a simple PHP test page.</p>
<p class="time">Current server time: <?php echo $currentTime; ?></p>
<h3>PHP Environment Information:</h3>
<p>PHP Version: <?php echo phpversion(); ?></p>
<p>Server Software: <?php echo $_SERVER['SERVER_SOFTWARE']; ?></p>
<p>Server Name: <?php echo $_SERVER['SERVER_NAME']; ?></p>
</body>
</html>
var_dump() – Wert und Datentyp ausgeben
Für Debugging-Zwecke gibt es in PHP var_dump(). Es gibt den Wert zusammen mit dem Datentyp aus – ähnlich wie console.log() in den DevTools, das ebenfalls Typinformationen anzeigt.
<?php
$greeting = "Hello, World!";
$currentTime = date("Y-m-d H:i:s");
?>
<p>var_dump($greeting): <code><?php var_dump($greeting); ?></code></p>
<p>var_dump($currentTime): <code><?php var_dump($currentTime); ?></code></p>
Arithmetische Operatoren
<h3>Addition</h3>
<p><?php echo 3+4; ?></p> //=7
<h3>Subtraktion</h3>
<p><?php echo 5-1; ?></p> //=4
<h3>Multiplikation</h3>
<p><?php echo 4*2; ?></p> //=8
<h3>Division</h3>
<p><?php echo 9/3; ?></p> //=3
<h3>Modulo</h3>
<p>Modulo gibt den <strong>Rest einer Division zurück.</p>
<p><?php echo 11%3; ?></p> //=2
<p><?php echo 12%3; ?></p> //=0
String concatenation
In JavaScript werden Strings mit + verkettet.
In PHP verwendet man stattdessen den Punkt . denn + ist in PHP ausschließlich für Zahlen reserviert.
<h3>String Concatenation</h3>
<p><code>// JS: console.log("I love to " + "code");</code></p>
<p>PHP: <?php echo "I love to " . "code"; ?></p>
Standardfunktionen
In JavaScript werden Methoden direkt auf Werte angewendet: "Hello".toUpperCase().
In PHP gibt es keine Methoden auf primitiven Typen. Stattdessen werden Funktionen verwendet, denen der Wert als Argument übergeben wird.
String-Methoden
toUpperCase()
// JS: console.log("Hello".toUpperCase()); // HELLO
<?php echo strtoupper("Hello"); ?>
startsWith()
// JS: console.log("Hey".startsWith("He")); // true
<?php var_dump(str_starts_with("Hey", "He")); ?>
// JS: console.log("Hey".startsWith("Hello")); // false
<?php var_dump(str_starts_with("Hey", "Hello")); ?>
trim() / trimStart() / trimEnd()
// JS: " Hello ".trim()
PHP trim() — entfernt Whitespace von beiden Seiten:
<?php var_dump(trim(" Hello ")); ?>
// JS: " Hello ".trimStart()
PHP ltrim() — entfernt Whitespace nur links:
<?php var_dump(ltrim(" Hello ")); ?>
// JS: " Hello ".trimEnd()
PHP rtrim() — entfernt Whitespace nur rechts:
<?php var_dump(rtrim(" Hello ")); ?>
// Ersten Buchstaben groß schreiben:
$str = "hello world";
echo ucfirst($str); // "Hello world"
// Alle Buchstaben groß:
$str = "hello world";
echo ucwords("$str"); // "Hello World"
Math-Methoden
Math.random()
// JS: console.log(Math.random()); // z.B. 0.4721...
In PHP gibt es keine direkte Entsprechung für eine zufällige Zahl zwischen 0 und 1.
Stattdessen verwendet man rand($min, $max) mit einem konkreten Bereich:
<?php echo rand(0, 100); ?>
Math.floor() - abrunden
// JS: Math.floor(4.7) // =4
<?php echo floor(4.7); ?>
Math.ceil() - aufrunden
// JS: Math.ceil(4.2) // =5
<?php echo ceil(4.2); ?>
Nesting
Funktionen können ineinander verschachtelt werden. PHP und JavaScript funktionieren hier identisch — die innerste Funktion wird zuerst ausgeführt.
// JS: console.log( Math.floor( Math.random() * 100 ) );
Da PHP kein Math.random() (Float 0–1) kennt, wird es wie folge aufgebaut:
mt_rand() / mt_getrandmax() ergibt eine zufällige Zahl zwischen 0 und 1.
<?php echo floor( mt_rand() / mt_getrandmax() * 100 ); ?>
Integer
// JS: console.log(Number.isInteger(2024)); // true
<?php var_dump(is_int(2024)); ?>
// JS: console.log(Number.isInteger(2024.5)); // false
<?php var_dump(is_int(2024.5)); ?>
Variablen und Konstanten
In JavaScript werden Variablen mit var, let oder const deklariert.
In PHP gibt es diese Schlüsselwörter nicht. Variablen beginnen immer mit $ und werden direkt durch Zuweisung erstellt.
var / let → einfache Zuweisung mit $
// JS: var name = "Alice";
// JS: let name = "Alice";
<?php $name = "Alice"; ?>
<?php var_dump($name); ?>
PHP-Variablen können jederzeit neu zugewiesen werden:
<?php $name = "Bob"; ?>
<?php var_dump($name); ?>
const → define()
// JS: const PI = 3.14;
PHP verwendet define() für Konstanten. Konstanten haben kein $-Zeichen.
PHP: float(3.14)
Kein Wert = undefined?
// JS: let x; // x ist undefined
In PHP gibt es kein undefined. Eine nicht gesetzte Variable hat den Wert null und erzeugt eine Warnung, wenn man auf sie zugreift.
Mit isset() prüft man, ob eine Variable gesetzt ist.
PHP isset($y): bool(false)
const ohne Wert / const neu zuweisen
// JS: const x; → SyntaxError
// JS: const x = 1; x = 2; → TypeError
In PHP muss define() immer einen Wert erhalten — sonst fehlt ein Argument (Fatal Error).
Eine einmal definierte Konstante kann nicht überschrieben werden; ein erneuter define()-Aufruf wird ignoriert und erzeugt eine Warnung.
Mathematische Zuweisungsoperatoren
Die mathematischen Zuweisungsoperatoren sind in PHP und JavaScript identisch. Statt let verwendet PHP $ für Variablen.
++ (um eins erhöhen)
// JS: let a = 1; a++; console.log(a); // 2
<?php $a = 1; $a++; ?>
<?php echo $a; ?>
+= (erhöhen um x)
// JS: let b = 2; b += 2; console.log(b); // 4
<?php $b = 2; $b += 2; ?>
<?php echo $b; ?>
-= (verringern um x)
// JS: let x = 20; x -= 5; console.log(x); // 15
<?php $x = 20; $x -= 5; ?>
<?php echo $x; ?>
*= (multiplizieren mit x)
// JS: let y = 50; y *= 2; console.log(y); // 100
<?php $y = 50; $y *= 2; ?>
<?php echo $y; ?>
/= (teilen durch x)
// JS: let z = 8; z /= 2; console.log(z); // 4
<?php $z = 8; $z /= 2; ?>
<?php echo $z; ?>
-- (um eins verringern)
// JS: let c = 5; c--; console.log(c); // 4
<?php $c = 5; $c--; ?>
<?php echo $c; ?>
PHP-Variablen an JavaScript übergeben
PHP wird serverseitig ausgeführt, bevor die Seite zum Browser gesendet wird. JavaScript sieht nur das fertige Ergebnis, die PHP-Tags sind bereits aufgelöst.
String
let name = "<?php echo $name; ?>";
Zahl
let zahl = <?php echo $zahl; ?>;
Array / Objekt → json_encode()
let daten = <?php echo json_encode($daten); ?>;
<?php
$name = "Alice";
$zahl = 42;
$daten = ["name" => "Alice", "alter" => 30];
?>
<script>
let name = "<?php echo $name; ?>";
let zahl = <?php echo $zahl; ?>;
let daten = <?php echo json_encode($daten); ?>;
console.log(name);
console.log(zahl);
console.log(daten);
//Öffne die Browser-Konsole (Strg + Umschalt + I), um die Ausgaben zu sehen.
</script>
Conditional Statements: if
In den Klammern () steht die Bedingung — sie wird als wahr oder falsch ausgewertet.
Wenn die Bedingung wahr ist, wird der Code in den geschweiften Klammern {} ausgeführt.
Wenn die Bedingung falsch ist, wird der Block übersprungen.
<?php
if (true) {
echo "<p>This message will print!</p>";
}
?>
<?php
$sale = true;
if ($sale) {
echo "<p>Buy now!</p>";
}
?>
<?php
$sale = false;
if ($sale) {
echo "<p>Buy now!</p>";
}
echo "<p>Ausgabe: (kein Output — Bedingung ist false)</p>";
?>
If … Else
// Der else-Block wird ausgeführt, wenn die Bedingung falsch ist.
<?php
if (false) {
echo "<p>The code in this block won't run!</p>";
} else {
echo "<p>But the code in this block will!</p>";
}
?>
<?php
$isMale = true;
if ($isMale) {
echo "<p>You are male</p>";
} else {
echo "<p>You are not male</p>";
}
?>
// if … else in einer Funktion
<?php
function handleModel($model) {
// Convert model to lowercase for case-insensitive comparison
$modelLower = strtolower($model);
// Check if model is o1 or o1-mini
if ($modelLower === 'o1' || $modelLower === 'o1-mini') {
// Code block for o1 or o1-mini models
// Add your specific code here
return 'o1/o1-mini code executed';
} else {
// Code block for all other models
// Add your specific code here
return 'other model code executed';
}
}
echo "<p>" . handleModel('o1') . "</p>"; // o1/o1-mini code executed
echo "<p>" . handleModel('o1-mini') . "</p>"; // o1/o1-mini code executed
echo "<p>" . handleModel('other') . "</p>"; // other model code executed
?>
if … elseif … else
Für mehr als zwei Fälle. In PHP wird elseif zusammen geschrieben.
<?php
$scores = [95, 72, 55, 34];
foreach ($scores as $score) {
if ($score >= 90) {
$label = "Sehr gut";
} elseif ($score >= 70) {
$label = "Gut";
} elseif ($score >= 50) {
$label = "Bestanden";
} else {
$label = "Durchgefallen";
}
echo "<p><code>score = $score</code> → <strong>$label</strong></p>";
}
?>
/*
score = 95 → Sehr gut
score = 72 → Gut
score = 55 → Bestanden
score = 34 → Durchgefallen
*/
Switch
PHP-switch funktioniert identisch zu JavaScript — gleiche Syntax, gleiches Verhalten.
<?php
$groceryItem = "papaya";
switch ($groceryItem) {
case "tomato":
echo "Tomatoes are 0.49 CHF";
break;
case "lime":
echo "Limes are 1.49 CHF";
break;
case "papaya":
echo "Papayas are 1.29 CHF";
break;
default:
echo "Invalid item";
break;
}
?>
Ohne break läuft die Ausführung in den nächsten Case weiter — in JS und PHP gleich.
<?php
$day = "Saturday";
switch ($day) {
case "Saturday":
case "Sunday":
echo "Wochenende";
break;
default:
echo "Werktag";
break;
}
?>
PHP-Besonderheit: === vs. ==
PHP switch vergleicht mit == (loose), nicht === (strict).
// JS: switch verwendet === Trifft zu! (0 == false in PHP switch)
In JavaScript würde switch (0) auf case false nicht zutreffen (weil ===).
match gibt einen Wert zurück und vergleicht strict — näher an JavaScript switch.
<?php
$status = 1;
$label = match($status) {
0 => "Inaktiv",
1 => "Aktiv",
2 => "Gesperrt",
default => "Unbekannt",
};
echo $label; // Aktiv
?>
Vergleichsoperatoren
Vergleichsoperatoren geben true oder false zurück.
< less than
<?php var_dump(10 < 12); ?> // bool(true)
<?php var_dump(12 < 10); ?> // bool(false)
> greater than
<?php var_dump(12 > 10); ?> // bool(true)
<?php var_dump(10 > 12); ?> // bool(false)
<= less than or equal to
<?php var_dump(10 <= 10); ?> // bool(true)
<?php var_dump(11 <= 10); ?> // bool(false)
>= greater than or equal to
<?php var_dump(10 >= 10); ?> // bool(true)
<?php var_dump(9 >= 10); ?> // bool(false)
== is equal to (loose)
<?php var_dump("5" == 5); ?> // bool(true)
<?php var_dump(0 == false); ?> // bool(true)
=== is equal to (strict — type & value)
<?php var_dump("5" === 5); ?> // bool(false)
<?php var_dump(5 === 5); ?> // bool(true)
<?php var_dump(0 === false); ?> // bool(false)
!== is not equal to (strict)
<?php var_dump("5" !== 5); ?> // bool(true)
<?php var_dump(5 !== 5); ?> // bool(false)
Logische Operatoren
Logische Operatoren verknüpfen Bedingungen und geben true oder false zurück.
&& and
Beide Bedingungen müssen wahr / true sein.
<?php var_dump(true && true); ?> // bool(true)
<?php var_dump(true && false); ?> // bool(false)
<?php var_dump(false && false); ?> // bool(false)
<?php
$age = 23;
if ($age >= 18 && $age < 65) {
echo "<p>Working age</p>";
} else {
echo "<p>Not working age</p>";
}
?>
// Working age
|| or
Mindestens eine Bedingung muss wahr sein.
<?php var_dump(true || false); ?> // bool(true)
<?php var_dump(false || false); ?> // bool(false)
<?php
$day = "Saturday";
if ($day === "Saturday" || $day === "Sunday") {
echo "<p>Weekend!</p>";
} else {
echo "<p>Work</p>";
}
?>
// Weekend!
! not
Kehrt den Wahrheitswert um.
<?php var_dump(!true); ?> // bool(false)
<?php var_dump(!false); ?> // bool(true)
<?php
$loggedIn = false;
if (!$loggedIn) {
echo "<p>Please log in</p>";
}
?>
// Please log in
„Truthy“ & „falsy“ assignment
Manche Werte gelten in einer Bedingung als wahr (truthy) oder falsch (falsy), ohne direkt true oder false zu sein. Use Cases wie Existenz-Checks oder Fallback-Werte.
// Statt
if ($username !== "" && $username !== null) { … }
// zu schreiben, kann man einfach:
if ($username) { ... }
// schreiben.
// Leerer String und null sind falsy.
Falsy-Werte in PHP. Diese Werte werden in einer if-Bedingung als false behandelt:
<?php
$values = [false, 0, 0.0, "", "0", [], null];
$labels = ['false', '0', '0.0', '""', '"0"', '[]', 'null'];
foreach ($values as $i => $val) {
$result = $val ? "truthy" : "falsy";
echo "<p><code>{$labels[$i]}</code> → $result</p>";
}
?>
/*
false → falsy
0 → falsy
0.0 → falsy
"" → falsy
"0" → falsy
[] → falsy
null → falsy
*/
Truthy-Werte in PHP. Alles andere gilt als true — zum Beispiel:
<?php
$values = [true, 1, -1, "hello", " ", [0]];
$labels = ['true', '1', '-1', '"hello"', '" " (Leerzeichen)', '[0]'];
foreach ($values as $i => $val) {
$result = $val ? "truthy" : "falsy";
echo "<p><code>{$labels[$i]}</code> → $result</p>";
}
?>
/*
true → truthy
1 → truthy
-1 → truthy
"hello" → truthy
" " (Leerzeichen) → truthy
[0] → truthy
*/
Zwei wichtige Unterschiede zu JavaScript:
| Wert | PHP | JavaScript |
|---|---|---|
"0" | falsy | truthy |
[] | falsy | truthy |
undefined | gibt es nicht | falsy |
NaN | gibt es nicht | falsy |
Wenn username irgendetwas Brauchbares enthält, nimm es, sonst nimm den Fallback. Egal ob username leer ist, null ist oder gar nicht gesetzt wurde.
In JavaScript gibt || den ersten truthy Wert zurück — nicht nur true/false.
In PHP gibt || immer nur einen Boolean zurück. Für dasselbe Muster gibt es den Elvis-Operator ?::
// JS: let defaultName = username || "Fremder";
// PHP: $defaultName = $username ?: "Fremder";
<?php
$username = "";
$defaultName = $username ?: "Fremder";
echo "<p>username = \"\" → defaultName: <strong>$defaultName</strong></p>"; // Fremder
$username = "Anna";
$defaultName = $username ?: "Fremder";
echo "<p>username = \"Anna\" → defaultName: <strong>$defaultName</strong></p>"; // Anna
?>
Code wird lesbarer, weil man nicht jeden Randfall einzeln prüfen muss. if ($items) prüft gleichzeitig ob das Array nicht leer ist — [] ist falsy, [1, 2, 3] ist truthy.
Der Nachteil: Es kann subtile Bugs erzeugen. 0 ist falsy — wenn $score = 0 ein gültiger Wert ist, wird if ($score) unerwartet false. Dann braucht man doch einen expliziten Check: if ($score !== null).
Ternary Operator
Der ternary Operator ist eine kürzere Schreibweise für einfache if/else-Ausdrücke.
JS-Beispiel mit if/else:
let isNightTime = true;
if (isNightTime) {
console.log("Turn on the lights!");
} else {
console.log("Turn off the lights!");
}
Gleiche Logik als ternary:
// JS: isNightTime ? "Turn on the lights!" : "Turn off the lights!"
Syntax: Bedingung ? Wert-wenn-wahr : Wert-wenn-falsch
In PHP ist die Syntax ist identisch:
<?php
$isNightTime = true;
$message = $isNightTime ? "Turn on the lights!" : "Turn off the lights!";
echo "<p>$message</p>"; //Turn on the lights!
$isNightTime = false;
$message = $isNightTime ? "Turn on the lights!" : "Turn off the lights!";
echo "<p>$message</p>"; //Turn off the lights!
?>
Direkt in echo. Die Klammern um den ternary Ausdruck sind bei echo nötig, damit PHP die Verkettung mit . korrekt auswertet.
// JS: console.log(isLoggedIn ? "Willkommen!" : "Bitte einloggen.")
<?php
$isLoggedIn = false;
echo "<p>" . ($isLoggedIn ? "Willkommen!" : "Bitte einloggen.") . "</p>";
$isLoggedIn = true;
echo "<p>" . ($isLoggedIn ? "Willkommen!" : "Bitte einloggen.") . "</p>";
?>
Wert zuweisen.
// JS: const label = score >= 50 ? "bestanden" : "durchgefallen"
<?php
$score = 72;
$label = $score >= 50 ? "bestanden" : "durchgefallen";
echo "<p>$label</p>";
$score = 34;
$label = $score >= 50 ? "bestanden" : "durchgefallen";
echo "<p>$label</p>";
?>
Zufallszahlen
JavaScript nutzt Math.random(), das einen Float zwischen 0 und 1 zurückgibt. Mit Math.floor() wird daraus eine ganze Zahl. PHP hat mit mt_rand() eine direktere Methode: Min und Max werden als Argumente übergeben.
// Zufallszahl von 0 bis 999
<?php $randomNumber = mt_rand(0, 999); echo $randomNumber; ?>
// Zufallszahl von 1 bis 6 (Würfel)
<?php $dice = mt_rand(1, 6); echo $dice; ?>
Unterschied:
JS: Math.floor(Math.random() * max) — Float 0–1, dann skalieren und abrunden.
PHP: mt_rand($min, $max) — gibt direkt eine ganze Zahl im Bereich zurück.
Funktionen
Funktionen ermöglichen es, eine bestimmte Aufgabe mehrfach auszuführen.
Sie stellen einen wiederverwendbaren Codeblock dar, der eine Folge von Anweisungen zusammenfasst, um eine bestimmte Aufgabe zu erfüllen.
In PHP werden Funktionen mit function deklariert — genau wie in JavaScript.
Einfache Funktion ohne Parameter:
<?php
function greetWorld() {
echo 'Hello World!';
}
?>
<?php greetWorld(); ?> // Hello World!
Funktion mit Parameter:
<?php
function greetPerson($name) {
echo 'Hello ' . $name;
}
?>
<?php greetPerson("Denis"); ?> // Hello Denis
Funktion mit Rückgabewert (return):
<?php
function begruessung($name) {
return "Hallo, {$name}!";
}
?>
<?php echo begruessung('Denis'); ?> // Hallo, Denis!
Zwei Zahlen addieren:
<?php
function addition($num1, $num2) {
return $num1 + $num2;
}
?>
<?php echo addition(4, 5); ?> // 9
Ergebnis in Variable speichern:
<?php
$summe = addition(4, 5);
?>
<?php echo $summe; ?> // 9
Zwei Zahlen multiplizieren:
<?php
// Funktion zur Multiplikation von zwei Zahlen
function multiplyNumbers($num1, $num2) {
return $num1 * $num2;
}
// Vom Benutzer bereitgestellte Eingaben
$number1 = 2;
$number2 = 3;
// Rufe die Funktion mit den Eingaben auf und speichere das Ergebnis in einer Variablen
$number3 = multiplyNumbers($number1, $number2);
?>
// Gib das Ergebnis aus
<?php echo "The result of multiplying {$number1} and {$number2} is {$number3}"; ?>
Klassen
Klassen fassen Daten und Methoden zu einer Einheit zusammen.
In PHP werden Klassen mit class definiert — genau wie in JavaScript.
Der Konstruktor heißt in PHP __construct() statt constructor().
Methoden greifen auf Eigenschaften der Klasse über $this zu.
Das vorherige Beispiel als Klasse:
<?php
class Multiplier {
public function multiplyNumbers($num1, $num2) {
return $num1 * $num2;
}
}
$multiplier = new Multiplier();
$number1 = 2;
$number2 = 3;
$number3 = $multiplier->multiplyNumbers($number1, $number2);
?>
<?php echo "The result of multiplying {$number1} and {$number2} is {$number3}"; ?>
//The result of multiplying 2 and 3 is 6
Klasse mit Konstruktor.
Der Konstruktor wird automatisch aufgerufen, wenn eine Instanz erstellt wird.
In JS: constructor() — in PHP: __construct()
<?php
class Greeter {
public $name;
public function __construct($name) {
$this->name = $name;
}
public function greet() {
return "Hallo, {$this->name}!";
}
}
$g = new Greeter("Denis");
?>
<?php echo $g->greet(); ?> // Hallo, Denis!
Array
Ein Array ist eine geordnete Sammlung von Elementen mit numerischem Index (beginnend bei 0).
In PHP wird ein Array mit [] oder array() erstellt — genau wie in JavaScript.
Der Zugriff auf Elemente erfolgt ebenfalls über den Index: $farben[0].
Array erstellen und auf Elemente zugreifen:
<?php
$farben = ['rot', 'grün', 'blau'];
?>
<?php echo $farben[0]; ?> // rot
<?php echo $farben[1]; ?> // grün
<?php echo $farben[2]; ?> // blau
Element ändern:
<?php
$farben[1] = 'violett';
?>
<?php var_dump($farben); ?>
// array(3) { [0]=> string(3) "rot" [1]=> string(7) "violett" [2]=> string(4) "blau" }
Loop über ein Array — klassische for-Schleife
JS: for (let i = 0; i < farben.length; i++) { console.log(farben[i]); }
In PHP: count() statt .length
<?php
$farben = ['rot', 'grün', 'blau'];
for ($i = 0; $i < count($farben); $i++) {
echo "<p>PHP: " . $farben[$i] . "</p>";
}
?>
// rot, grün, blau - jeweils in einer neuen Zeile
Foreach
Loop über ein Array — foreach
<?php
$farben = ['rot', 'grün', 'blau'];
foreach ($farben as $farbe) {
echo "<p>PHP: " . $farbe . "</p>";
}
?>
In PHP: Strings sind nicht direkt iterierbar.str_split($text) wandelt den String in ein Array von Zeichen um.
<?php
$text = "Hallo";
foreach (str_split($text) as $buchstabe) {
echo "<p>PHP: " . $buchstabe . "</p>";
}
?>
// H, a, l, l, o - jeweils in einer neuen Zeile
In JavaScript iteriert for...in über die Eigenschaften (Schlüssel) eines Objekts.
In PHP gibt es kein Objekt-Literal — stattdessen verwendet man ein assoziatives Array.
Die Schleife dafür lautet foreach ($array as $schluessel => $wert).
// JS: for (let eintrag in person) { console.log(`${eintrag}: ${person[eintrag]}`); }
// In JS liefert for...in nur den Schlüssel — der Wert muss über person[eintrag] abgerufen werden.
// In PHP liefert foreach mit => direkt beides — kompakter und lesbarer.
<?php
$person = ['name' => 'Denis', 'alter' => 42, 'beruf' => 'Berater'];
?>
<?php var_dump($person); ?>
// array(3) { ["name"]=> string(5) "Denis" ["alter"]=> int(42) ["beruf"]=> string(7) "Berater" }
<?php
foreach ($person as $eintrag => $wert) {
echo "<p>PHP: $eintrag: $wert</p>";
}
?>
For Schleife
For Schleife durchläuft einen Codeblock mehrmals in einer Schleife. Sie besteht aus drei Teilen: Initialisierung (Startwert setzen), Bedingung (Wiederholungsbedingung), Inkrement/Dekrement (Wertänderung pro Durchlauf).
PHP verwendet dieselbe Syntax wie JavaScript:
<?php
for ($i = 0; $i < 5; $i++) {
echo "<p>Durchlauf Nummer: $i</p>";
}
?>
// 0, 1, 2, 3, 4 - jeweils in einer neuen Zeile
Array durchlaufen. In PHP: count($array) statt array.length (JavaScript)
<?php
$farben = ['rot', 'grün', 'blau'];
for ($i = 0; $i < count($farben); $i++) {
echo "<p>$farben[$i]</p>";
}
?>
// rot, grün, blau - jeweils in einer neuen Zeile
GET
GET überträgt Daten über die URL — sichtbar in der Adresszeile als ?key=value&key2=value2.
//URL-Beispiel: index.php?name=Denis&alter=44
<?php
$name = $_GET['name'] ?? 'unbekannt';
$alter = $_GET['alter'] ?? 'unbekannt';
?>
<p>Name: <?php echo htmlspecialchars($name); ?></p> // Name: Denis
<p>Alter: <?php echo htmlspecialchars($alter); ?></p> // Alter: 44
Nicht geeignet für Passwörter oder sensible Daten, da die Parameter in der URL, im Browserverlauf und in Server-Logs sichtbar sind. Dafür nimmt man POST.
POST
$_POST ist wie $_GET, aber die Daten kommen nicht aus der URL sondern aus dem Request-Body des Formulars.
$_SERVER['REQUEST_METHOD'] prüft, ob das Formular abgeschickt wurde — beim ersten Laden der Seite ist es GET, nach dem Absenden POST. Erst dann lohnt es sich, $_POST auszulesen. Die leeren Strings als Startwert verhindern, dass PHP eine Warnung wirft, wenn die Variablen vor dem ersten Submit im Template verwendet werden.
<?php
$name = '';
$alter = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['name'] ?? '';
$alter = $_POST['alter'] ?? '';
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>POST-Parameter</title>
</head>
<body>
<h1>POST-Parameter</h1>
<form method="post">
<label>Name: <input type="text" name="name" value="<?php echo htmlspecialchars($name); ?>"></label><br><br>
<label>Alter: <input type="number" name="alter" value="<?php echo htmlspecialchars($alter); ?>"></label><br><br>
<button type="submit">Absenden</button>
</form>
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST'): ?>
<hr>
<p>Name: <?php echo htmlspecialchars($name); ?></p>
<p>Alter: <?php echo htmlspecialchars($alter); ?></p>
<?php endif; ?>
</body>
</html>
SSL Proxy
https://ssl.webpack.de/test.denisreis.de/
Laravel
Hilfreiche Links
- Laravel 13.x Dokumentation
- Laracast
- Laravel From Scratch (2026 Edition)
- VS Extension – Atom Material Theme
- VS Extension – Atom Material Icons – anschließend Set File Icon Theme anklicken und auswählen
Laravel Installation
Offiziele doku hier. Sie können auch Herd für visuelle Installation nutzen.
Install Composer. Composer ist ein Paketmanager bzw. Abhängigkeitsmanager für PHP.
Der Installer fügt Composer automatisch zu deinem PATH hinzu. Installation prüfen:
composer -v
In C:\php\php.ini folgende extensions aktivieren. Sind standardmäßig auskommentiert. ; löschen
extension=zip
extension=fileinfo
extension=mysqli
Anschließend Laravel installieren. Im Terminal ausführen:
composer global require laravel/installer

Installation prüfen. Im Terminal:
laravel
Laravel Projekt anlegen
Zu dem Projekt Verzeichnis navigieren. Im Terminal:
laravel new <projekt_name>
laravel new mein_projekt
Sie können zunächst die Standardoptionen übernehmen. Kein Starter Kit (es sei denn Sie wollen explizit mit React oder Svelte für JS arbeiten), Pest als Testing Framework, usw.

Vor dem Schritt der Datenbankmigration müssen Sie eine Datenbank einrichten und einen Benutzer anlegen.
CREATE DATABASE IF NOT EXISTS mein_projekt
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
CREATE USER 'mp_user'@'localhost' IDENTIFIED WITH caching_sha2_password BY '***';GRANT USAGE ON *.* TO 'mp_user'@'localhost'; ALTER USER 'mp_user'@'localhost' ;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER ON `mein\_projekt`.* TO 'mp_user'@'localhost'; ALTER USER 'mp_user'@'localhost' ;
Anschließend müssen Sie die .env Datei im <projekt_name> z.B. mein-projekt anpassen.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mein_projekt
DB_USERNAME=root
DB_PASSWORD=cdKVdQ3W...
Sie können die Migration auch manuell nachholen:
cd mein_projekt
php artisan migrate

Dabei werden alle relevanten Tabellen angelegt.
Sobald Sie den Entwicklungsserver gestartet haben, ist Ihre Anwendung in Ihrem Webbrowser unter http://localhost:8000 erreichbar.
http://localhost:8000

Laravel Glossar
Begriffsklärung für Laravel Einsteiger.
Route
Die Zuordnung URL → Aktion. In Dateien wie routes/web.php legst du fest, was passieren soll, wenn jemand eine
bestimmte URL aufruft (z. B. / oder /kontakt). Die Route entscheidet, ob eine View angezeigt oder ein Controller
ausgeführt wird.
Route kann einen Controller oder direkt eine View aufrufen.
Faustregel:
- Closure in der Route → praktisch für ganz einfache Seiten oder Prototypen.
- Controller → sobald Logik dazukommt (Datenbankabfragen, Validierung, mehrere Aktionen) — sauberer und besser
testbar.
View
Die Darstellungsschicht — also das, was im Browser angezeigt wird (HTML). Views liegen in resources/views/ und
enden meist auf .blade.php. Sie enthalten das Markup der Seite, aber keine Logik.
Controller
Die Vermittlungsschicht zwischen Route und View. Ein Controller ist eine PHP-Klasse (in app/Http/Controllers/),
die eingehende Anfragen verarbeitet, Daten aus dem Model holt und am Ende eine View mit diesen Daten zurückgibt.
So bleibt die web.php schlank.
Blade
Die Template-Engine von Laravel. Mit Blade kannst du in .blade.php-Dateien dynamische Inhalte mit kurzen
Direktiven einbauen, z. B. {{ $name }} zur Ausgabe einer Variable oder @if, @foreach, @extends für Logik und
Layouts. Blade wird vor der Auslieferung in reines PHP/HTML kompiliert.
Zusammenspiel (MVC-Kette):
Route → ruft Controller auf → holt Daten (z. B. via Model) → übergibt sie an die View → Blade rendert HTML →
Browser zeigt die Seite.
Laravel-Installation – Order und Dateien Übersicht
Top-Level-Ordner
| Ordner | Zweck |
|---|---|
| app/ | Herzstück deiner Anwendung – enthält Controller, Models, Service-Provider und sonstige Kern-Klassen |
| app/Http/ | HTTP-Schicht: Controller, Middleware, Form-Requests |
| app/Models/ | Eloquent-Models (z. B. User.php) – die Brücke zur Datenbank |
| app/Providers/ | Service-Provider, die beim Booten der App ausgeführt werden |
| bootstrap/ | App-Bootstrapping (app.php, providers.php) und Cache-Dateien des Frameworks |
| config/ | Alle Konfigurationsdateien (app.php, database.php, mail.php …) |
| database/ | Datenbank-Artefakte: Migrationen, Seeders, Factories |
| database/migrations/ | Schema-Versionierung (Tabellen anlegen / ändern) |
| database/seeders/ | Klassen zum Befüllen der DB mit Testdaten |
| database/factories/ | Model-Factories für Tests / Seeding (Faker-basiert) |
| public/ | Webroot – einziger öffentlich erreichbarer Ordner. Enthält index.php (Front-Controller), Assets, favicon.ico, robots.txt |
| public/build/ | Vite-Build-Output (compiled CSS/JS) |
| resources/ | Quell-Dateien für Frontend & Views |
| resources/views/ | Blade-Templates (*.blade.php) |
| resources/css/ | CSS-Quelldateien (werden von Vite verarbeitet) |
| resources/js/ | JS-Quelldateien (Vite-Entry-Points) |
| routes/ | Routen-Definitionen |
| routes/web.php | Web-Routen (Sessions, CSRF) |
| routes/console.php | Artisan-Closure-Befehle |
| storage/ | Schreib-Bereich für die App – muss beschreibbar sein |
| storage/app/ | Anwendungs-Dateien (Uploads etc.) |
| storage/framework/ | Framework-interne Caches, Sessions, kompilierte Views |
| storage/logs/ | Log-Dateien (laravel.log) |
| tests/ | PHPUnit-/Pest-Tests |
| tests/Feature/ | High-Level-/HTTP-Tests |
| tests/Unit/ | Isolierte Unit-Tests |
| vendor/ | Composer-Abhängigkeiten (von Composer verwaltet, nicht manuell anfassen) |
| node_modules/ | NPM-Abhängigkeiten für das Frontend-Tooling (Vite etc.) |
Top-Level-Dateien
| Datei | Zweck |
|---|---|
| artisan | CLI-Einstiegspunkt für Laravel (php artisan migrate, make:model …) |
| composer.json | PHP-Abhängigkeiten + Autoload-Konfiguration |
| composer.lock | Exakte installierte PHP-Paket-Versionen (festgeschrieben) |
| package.json | NPM-Abhängigkeiten + Build-Scripts (Vite) |
| package-lock.json | Exakte installierte NPM-Paket-Versionen |
| vite.config.js | Build-Konfiguration des Asset-Bundlers Vite |
| phpunit.xml | PHPUnit-/Pest-Test-Konfiguration |
| .env | Umgebungs-Variablen (DB-Credentials, App-Key, Mailer …) – nicht ins Git! |
| .env.example | Vorlage für .env, wird committet |
| .gitignore | Welche Dateien Git ignorieren soll (vendor/, node_modules/, .env …) |
| .gitattributes | Git-Behandlung pro Datei (Line-Endings, Export-Ignore) |
| .editorconfig | Editor-übergreifende Code-Style-Regeln (Tabs, Encoding …) |
| .npmrc | NPM-Konfiguration (z. B. engine-strict) |
| README.md | Standard-Laravel-Readme (kannst du überschreiben) |
| CLAUDE.md | Projekt-Anweisungen für Claude Code |
| .mcp.json | MCP-Server-Konfiguration für Claude Code |
| boost.json | Konfig der Laravel-Boost-Erweiterung (AI-Tooling) |
| .claude/ | Projekt-spezifische Claude-Code-Einstellungen |
Daumenregel
- Was du anfasst:
app/,config/,database/,resources/,routes/,tests/,.env - Was generiert/abhängig ist (nie manuell editieren):
vendor/,node_modules/,bootstrap/cache/,storage/framework/,public/build/ - Webserver zeigt nur auf:
public/
Projekt bearbeiten
Sobald die Anwendung erstellt wurde, können Sie den lokalen Entwicklungsserver von Laravel, den Queue-Worker und den Vite-Entwicklungsserver mit dem dev Composer-Skript starten (node.js muss vorher installiert werden):
cd mein_projekt
npm install && npm run build
composer run dev
Wenn Sie zurück kommen und an Ihrem Projekt weiterabeiten, brauchen Sie npm install && npm run build nicht auszuführen. Führen Sie einfach die folgenden Befehle aus.
cd mein_projekt
composer run dev
Beziehungsweise:
cd mein_projekt && composer run dev
cd mein_projekt wechselt in den Projektordner. && bedeutet: führe den nächsten Befehl nur aus, wenn der erste
erfolgreich war. composer run dev startet dann den Laravel-Server, die Queue und Vite gleichzeitig.
Sie können auch zwei Projekte parallel laufen lassen:
cd mein_zweites_projekt
npx concurrently -c "#93c5fd,#c4b5fd,#fdba74" "php artisan serve --port=8002" "php artisan queue:listen --tries=1" "npm run dev -- --port=5174" --names='server,queue,vite'
Routes
Die Datei routes/web.php ist die zentrale Routing-Datei für die Web-Oberfläche deiner Laravel-Anwendung. Hier definierst du, welche URL (z. B. /, /about, /users) welche Aktion auslöst — also entweder direkt eine View zurückgibt oder einen Controller aufruft. Routen in dieser Datei erhalten automatisch die web-Middleware-Gruppe, die u. a. Sessions, CSRF-Schutz und Cookies aktiviert (im Gegensatz zu routes/api.php, das zustandslos für APIs gedacht ist).
Betrachten wir das folgende Beispiel. Wenn jemand die Startseite (/) per GET aufruft, wird die Blade-View resources/views/welcome.blade.php zurückgegeben.

<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('landingpage'); // redirect auf eine andere view
});
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::get('/landing', function () {
return view('landingpage');
});
Einfache View Routes können auch abgekürzt definiert werden:
<?php
use Illuminate\Support\Facades\Route;
Route::view('/', 'welcome');
Route::view('/about', 'about');
Route::view('/contact', 'contact');
Views
CSS sollte mit @vite hinzugefügt werden, damit Hot Reload funktioniert. @vite() aktiviert Hot Reload und sorgt im Production-Build dafür, dass die richtige gehashte CSS-Datei verlinkt wird.
@vite(['resources/css/landingpage.css'])
Voraussetzung ist, dass der Vite Server läuft. composer run dev startet dann den Laravel-Server, die Queue und Vite gleichzeitig.
cd mein_projekt && composer run dev
Layout page
Eine Layout-Page ist eine wiederverwendbare Hülle (Template), die das gemeinsame HTML-Gerüst aller Seiten einer
Anwendung enthält. Ohne Layout müsste jede View das , usw. wiederholen. Mit dem Layout schreibt man das einmal
zentral — Änderungen am Design (z.B. Navigation, CSS) gelten dann automatisch für alle Seiten.
Zum Beispiel in views/components/layout.blade.php
@props([
'title' => 'Default Title'
])
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{$title}}</title>
@vite(['resources/css/landingpage.css'])
</head>
<body>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About Us</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
<main>
{{ $slot }}
</main>
</body>
</html>
In individuelen Blades, z.B. welcome.blade.php
<x-layout title="Home"> //wird an layout.blade.php übergeben
// das nachfolgende wird in {{ $slot }} ausgegeben
<h1>Welcome to our Landing Page!</h1>
<p>This is the main page of our website. Here you can find information about our services and products. Feel free to explore and learn more about what we have to offer.</p>
</x-layout>
Test Commands
Test commands (run from mein_projekt/)
Full suite:
composer test
This is the standard — runs artisan config:clear then artisan test. 142 tests today
Per testsuite (gemäss phpunit.xml im Projektverzeichnis):
php artisan test --testsuite=Feature
php artisan test --testsuite=Browser
php artisan test --testsuite=Arch
php artisan test --testsuite=Unit
Filter by name or file:
php artisan test --compact --filter=SitemapTest
php artisan test tests/Feature/ContactValidationTest.php
Compact output:
php artisan test --compact
With coverage:
Runs the test suite and prints a code-coverage report — per-file percentages showing which lines of production code under app/ (that’s the block in phpunit.xml) were executed by tests and which weren’t.
php artisan test --coverage
Browser tests need sockets extensions enabled in php.ini plus npx playwright install chromium run once.
Local Production Build
npm run build führt vite build aus (gemäß package.json) und macht folgendes:
- Bündelt alle JS- und CSS-Dateien in wenige optimierte Dateien
- Kompiliert Tailwind CSS — nur die tatsächlich genutzten Klassen landen im Output (kein ungenutztes CSS)
- Minifiziert alles (kleinere Dateigröße, schnellere Ladezeiten)
- Schreibt die Dateien mit Hash im Dateinamen nach public/build/ (z.B. app-a1b2c3d4.js)
- Erstellt ein manifest.json — damit weiß Laravels @vite()-Direktive im Blade-Template, welche Datei es einbinden
soll Das Ergebnis ist produktionsreif und muss committed werden, damit es auf dem Server verfügbar ist.
Composer ist ein Paketmanager bzw. Abhängigkeitsmanager für PHP.
cd mein_projekt
npm ci
npm run build




Hinterlasse einen Kommentar
An der Diskussion beteiligen?Hinterlasse uns deinen Kommentar!