Coding-Guidelines aktualisiert
parent
efa37f142c
commit
c413077b4e
@ -1,338 +1,338 @@
|
||||
# PHP Coding Guidelines
|
||||
|
||||
Diese Coding-Guidelines gelten für alle PHP-Projekte der Anwendungsentwickler-Klasse.
|
||||
Ziel ist ein einheitlicher, gut lesbarer und wartbarer Code-Stil, damit alle im Team effizient zusammenarbeiten können.
|
||||
|
||||
---
|
||||
|
||||
## 1. Allgemeine Grundsätze
|
||||
|
||||
- Wir verwenden **PHP 8.x**.
|
||||
- Wir schreiben möglichst **typsicheren Code** (Parameter- und Rückgabetypen).
|
||||
- Lesbarkeit steht über Cleverness.
|
||||
- Duplizierten Code vermeiden („Don’t Repeat Yourself“).
|
||||
|
||||
---
|
||||
|
||||
## 2. Projektstruktur
|
||||
|
||||
Beispielstruktur:
|
||||
|
||||
```text
|
||||
projektname/
|
||||
├─ public/
|
||||
├─ src/
|
||||
│ ├─ Controller/
|
||||
│ ├─ Model/
|
||||
│ ├─ View/
|
||||
│ └─ Service/
|
||||
├─ config/
|
||||
├─ templates/
|
||||
├─ vendor/
|
||||
└─ composer.json
|
||||
```
|
||||
|
||||
Regeln:
|
||||
|
||||
- Öffentlich zugängliche Dateien nur in `public/`.
|
||||
- Alle Klassen in `src/`.
|
||||
- Keine Konfigurationswerte hart im Code.
|
||||
|
||||
---
|
||||
|
||||
## 3. Dateien & Encoding
|
||||
|
||||
- `.php` Endung.
|
||||
- UTF-8 ohne BOM.
|
||||
- Datei beginnt mit `<?php` und ohne schließendes `?>`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Namespaces & Autoloading
|
||||
|
||||
- PSR-4 Autoloading.
|
||||
- Namespace spiegelt Ordnerstruktur wider.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace SchoolApp\User;
|
||||
|
||||
class UserService
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Namenskonventionen
|
||||
|
||||
### Klassen
|
||||
|
||||
- PascalCase
|
||||
`UserController`, `InvoiceService`
|
||||
|
||||
### Interfaces
|
||||
|
||||
- PascalCase + `Interface`
|
||||
`UserRepositoryInterface`
|
||||
|
||||
### Methoden & Funktionen
|
||||
|
||||
- camelCase
|
||||
`getUserById()`
|
||||
|
||||
### Variablen / Eigenschaften
|
||||
|
||||
- camelCase
|
||||
`$userName`
|
||||
|
||||
### Konstanten
|
||||
|
||||
- UPPER_SNAKE_CASE
|
||||
`MAX_LOGIN_ATTEMPTS`
|
||||
|
||||
---
|
||||
|
||||
## 6. Formatierung & Einrückung
|
||||
|
||||
- 4 Leerzeichen.
|
||||
- Zeilenlänge max. 120 Zeichen.
|
||||
- Öffnende Klammer in derselben Zeile.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```php
|
||||
if ($condition) {
|
||||
// ...
|
||||
} else {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Typen & strikte Typisierung
|
||||
|
||||
- Am Anfang der Datei:
|
||||
|
||||
```php
|
||||
declare(strict_types=1);
|
||||
```
|
||||
|
||||
- Parameter- und Rückgabetypen nutzen.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```php
|
||||
public function findUserById(int $id): ?User
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
- Nullable Typen:
|
||||
|
||||
```php
|
||||
?string
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Arrays & Strings
|
||||
|
||||
### Arrays
|
||||
|
||||
Kurzsyntax:
|
||||
|
||||
```php
|
||||
$items = [
|
||||
'apple',
|
||||
'banana',
|
||||
];
|
||||
```
|
||||
|
||||
### Strings
|
||||
|
||||
- `'...'` ohne Variablen
|
||||
- `"..."` mit Variablen
|
||||
|
||||
---
|
||||
|
||||
## 9. Objektorientierung
|
||||
|
||||
### Sichtbarkeit
|
||||
|
||||
- Standard: `private`
|
||||
- Nur wenn nötig `protected` oder `public`.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```php
|
||||
class User
|
||||
{
|
||||
private string $name;
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Konstruktor-Injection
|
||||
|
||||
```php
|
||||
public function __construct(
|
||||
private InvoiceRepositoryInterface $repo
|
||||
) {}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Fehlerbehandlung & Exceptions
|
||||
|
||||
- Keine `die()`, `exit()`, `var_dump()` im Produktivcode.
|
||||
- Exceptions statt Abbrüche.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```php
|
||||
throw new UserNotFoundException("User not found");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Kommentare & PHPDoc
|
||||
|
||||
- Kommentare erklären *warum*, nicht *was*.
|
||||
|
||||
Schlecht:
|
||||
|
||||
```php
|
||||
// increment i
|
||||
$i = $i + 1;
|
||||
```
|
||||
|
||||
### PHPDoc
|
||||
|
||||
```php
|
||||
/**
|
||||
* Berechnet die Gesamtsumme einer Rechnung.
|
||||
*/
|
||||
public function calculateTotal(Invoice $invoice): float
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. Sicherheit
|
||||
|
||||
### Eingaben validieren
|
||||
|
||||
```php
|
||||
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
|
||||
```
|
||||
|
||||
### SQL Injection vermeiden
|
||||
|
||||
```php
|
||||
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
|
||||
$stmt->execute(['email' => $email]);
|
||||
```
|
||||
|
||||
### XSS verhindern
|
||||
|
||||
```php
|
||||
<?= htmlspecialchars($userName, ENT_QUOTES, 'UTF-8') ?>
|
||||
```
|
||||
|
||||
### Passwörter
|
||||
|
||||
```php
|
||||
password_hash($pw, PASSWORD_DEFAULT);
|
||||
password_verify($pw, $hash);
|
||||
```
|
||||
|
||||
### CSRF-Token
|
||||
|
||||
```html
|
||||
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 13. Git-Workflow
|
||||
|
||||
- Häufige, kleine Commits.
|
||||
- Commit-Messages im Imperativ:
|
||||
- `Add login form`
|
||||
- `Fix session timeout`
|
||||
- Keine sensiblen Daten committen.
|
||||
- `.gitignore` für:
|
||||
- `vendor/`
|
||||
- `.idea/`
|
||||
- `.vscode/`
|
||||
- `logs/`
|
||||
- `cache/`
|
||||
|
||||
---
|
||||
|
||||
## 14. Code-Review-Regeln
|
||||
|
||||
- Review vor jedem Merge.
|
||||
- Kritik ist sachlich.
|
||||
- Reviewer geben konkrete Vorschläge.
|
||||
|
||||
---
|
||||
|
||||
## 15. Beispiel-Code
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SchoolApp\User;
|
||||
|
||||
use PDO;
|
||||
|
||||
class UserRepository implements UserRepositoryInterface
|
||||
{
|
||||
public function __construct(private PDO $connection)
|
||||
{
|
||||
}
|
||||
|
||||
public function findByEmail(string $email): ?User
|
||||
{
|
||||
$sql = 'SELECT id, name, email FROM users WHERE email = :email';
|
||||
|
||||
$stmt = $this->connection->prepare($sql);
|
||||
$stmt->execute(['email' => $email]);
|
||||
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($data === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new User(
|
||||
(int) $data['id'],
|
||||
(string) $data['name'],
|
||||
(string) $data['email']
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 16. Weiterentwicklung
|
||||
|
||||
- Guidelines sind lebendig.
|
||||
- Änderungen im Team besprechen.
|
||||
- Aktualisierungen per Pull-Request.
|
||||
|
||||
---
|
||||
# PHP Coding Guidelines
|
||||
|
||||
Diese Coding-Guidelines gelten für alle PHP-Projekte der Anwendungsentwickler-Klasse.
|
||||
Ziel ist ein einheitlicher, gut lesbarer und wartbarer Code-Stil, damit alle im Team effizient zusammenarbeiten können.
|
||||
|
||||
---
|
||||
|
||||
## 1. Allgemeine Grundsätze
|
||||
|
||||
- Wir verwenden **PHP 8.x**.
|
||||
- Wir schreiben möglichst **typsicheren Code** (Parameter- und Rückgabetypen).
|
||||
- Lesbarkeit steht über Cleverness.
|
||||
- Duplizierten Code vermeiden („Don’t Repeat Yourself“).
|
||||
|
||||
---
|
||||
|
||||
## 2. Projektstruktur
|
||||
|
||||
Beispielstruktur:
|
||||
|
||||
```text
|
||||
projektname/
|
||||
├─ public/
|
||||
├─ src/
|
||||
│ ├─ Controller/
|
||||
│ ├─ Model/
|
||||
│ ├─ View/
|
||||
│ └─ Service/
|
||||
├─ config/
|
||||
├─ templates/
|
||||
├─ vendor/
|
||||
└─ composer.json
|
||||
```
|
||||
|
||||
Regeln:
|
||||
|
||||
- Öffentlich zugängliche Dateien nur in `public/`.
|
||||
- Alle Klassen in `src/`.
|
||||
- Keine Konfigurationswerte hart im Code.
|
||||
|
||||
---
|
||||
|
||||
## 3. Dateien & Encoding
|
||||
|
||||
- `.php` Endung.
|
||||
- UTF-8 ohne BOM.
|
||||
- Datei beginnt mit `<?php` und ohne schließendes `?>`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Namespaces & Autoloading
|
||||
|
||||
- PSR-4 Autoloading.
|
||||
- Namespace spiegelt Ordnerstruktur wider.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace SchoolApp\User;
|
||||
|
||||
class UserService
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Namenskonventionen
|
||||
|
||||
### Klassen
|
||||
|
||||
- PascalCase
|
||||
`UserController`, `InvoiceService`
|
||||
|
||||
### Interfaces
|
||||
|
||||
- PascalCase + `Interface`
|
||||
`UserRepositoryInterface`
|
||||
|
||||
### Methoden & Funktionen
|
||||
|
||||
- camelCase
|
||||
`getUserById()`
|
||||
|
||||
### Variablen / Eigenschaften
|
||||
|
||||
- camelCase
|
||||
`$userName`
|
||||
|
||||
### Konstanten
|
||||
|
||||
- UPPER_SNAKE_CASE
|
||||
`MAX_LOGIN_ATTEMPTS`
|
||||
|
||||
---
|
||||
|
||||
## 6. Formatierung & Einrückung
|
||||
|
||||
- 4 Leerzeichen.
|
||||
- Zeilenlänge max. 120 Zeichen.
|
||||
- Öffnende Klammer in derselben Zeile.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```php
|
||||
if ($condition) {
|
||||
// ...
|
||||
} else {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Typen & strikte Typisierung
|
||||
|
||||
- Am Anfang der Datei:
|
||||
|
||||
```php
|
||||
declare(strict_types=1);
|
||||
```
|
||||
|
||||
- Parameter- und Rückgabetypen nutzen.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```php
|
||||
public function findUserById(int $id): ?User
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
- Nullable Typen:
|
||||
|
||||
```php
|
||||
?string
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Arrays & Strings
|
||||
|
||||
### Arrays
|
||||
|
||||
Kurzsyntax:
|
||||
|
||||
```php
|
||||
$items = [
|
||||
'apple',
|
||||
'banana',
|
||||
];
|
||||
```
|
||||
|
||||
### Strings
|
||||
|
||||
- `'...'` ohne Variablen
|
||||
- `"..."` mit Variablen
|
||||
|
||||
---
|
||||
|
||||
## 9. Objektorientierung
|
||||
|
||||
### Sichtbarkeit
|
||||
|
||||
- Standard: `private`
|
||||
- Nur wenn nötig `protected` oder `public`.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```php
|
||||
class User
|
||||
{
|
||||
private string $name;
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Konstruktor-Injection
|
||||
|
||||
```php
|
||||
public function __construct(
|
||||
private InvoiceRepositoryInterface $repo
|
||||
) {}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Fehlerbehandlung & Exceptions
|
||||
|
||||
- Keine `die()`, `exit()`, `var_dump()` im Produktivcode.
|
||||
- Exceptions statt Abbrüche.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```php
|
||||
throw new UserNotFoundException("User not found");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Kommentare & PHPDoc
|
||||
|
||||
- Kommentare erklären *warum*, nicht *was*.
|
||||
|
||||
Schlecht:
|
||||
|
||||
```php
|
||||
// increment i
|
||||
$i = $i + 1;
|
||||
```
|
||||
|
||||
### PHPDoc
|
||||
|
||||
```php
|
||||
/**
|
||||
* Berechnet die Gesamtsumme einer Rechnung.
|
||||
*/
|
||||
public function calculateTotal(Invoice $invoice): float
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. Sicherheit
|
||||
|
||||
### Eingaben validieren
|
||||
|
||||
```php
|
||||
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
|
||||
```
|
||||
|
||||
### SQL Injection vermeiden
|
||||
|
||||
```php
|
||||
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
|
||||
$stmt->execute(['email' => $email]);
|
||||
```
|
||||
|
||||
### XSS verhindern
|
||||
|
||||
```php
|
||||
<?= htmlspecialchars($userName, ENT_QUOTES, 'UTF-8') ?>
|
||||
```
|
||||
|
||||
### Passwörter
|
||||
|
||||
```php
|
||||
password_hash($pw, PASSWORD_DEFAULT);
|
||||
password_verify($pw, $hash);
|
||||
```
|
||||
|
||||
### CSRF-Token
|
||||
|
||||
```html
|
||||
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 13. Git-Workflow
|
||||
|
||||
- Häufige, kleine Commits.
|
||||
- Commit-Messages im Imperativ:
|
||||
- `Add login form`
|
||||
- `Fix session timeout`
|
||||
- Keine sensiblen Daten committen.
|
||||
- `.gitignore` für:
|
||||
- `vendor/`
|
||||
- `.idea/`
|
||||
- `.vscode/`
|
||||
- `logs/`
|
||||
- `cache/`
|
||||
|
||||
---
|
||||
|
||||
## 14. Code-Review-Regeln
|
||||
|
||||
- Review vor jedem Merge.
|
||||
- Kritik ist sachlich.
|
||||
- Reviewer geben konkrete Vorschläge.
|
||||
|
||||
---
|
||||
|
||||
## 15. Beispiel-Code
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SchoolApp\User;
|
||||
|
||||
use PDO;
|
||||
|
||||
class UserRepository implements UserRepositoryInterface
|
||||
{
|
||||
public function __construct(private PDO $connection)
|
||||
{
|
||||
}
|
||||
|
||||
public function findByEmail(string $email): ?User
|
||||
{
|
||||
$sql = 'SELECT id, name, email FROM users WHERE email = :email';
|
||||
|
||||
$stmt = $this->connection->prepare($sql);
|
||||
$stmt->execute(['email' => $email]);
|
||||
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($data === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new User(
|
||||
(int) $data['id'],
|
||||
(string) $data['name'],
|
||||
(string) $data['email']
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 16. Weiterentwicklung
|
||||
|
||||
- Guidelines sind lebendig.
|
||||
- Änderungen im Team besprechen.
|
||||
- Aktualisierungen per Pull-Request.
|
||||
|
||||
---
|
||||
|
||||
Loading…
Reference in New Issue
Block a user