Skip to content

Dobre praktyki pisania kodu PHP

This content is not available in your language yet.

Dobre praktyki programistyczne to sprawdzone zasady, które pomagaja pisac kod łatwiejszy do zrozumienia, utrzymania i rozwijania. W PHP szczegolnie ważne jest przestrzeganie tych zasad, ponieważ język pozwala na wiele “skrotow”, które prowadza do trudnego w utrzymaniu kodu.

Czysty kod to nie tylko estetyka - to oszczednosc czasu, mniej błędów i lepsza współpraca w zespole.

Kod, który jest łatwy do zrozumienia i modyfikacji. Każda funkcja robi jedna rzecz, nazwy sa opisowe, a struktura jest przejrzysta.

Nie powtarzaj kodu - jeśli cos piszesz dwa razy, zrob z tego funkcje.

Proste rozwiązania sa lepsze od skomplikowanych.

Piec zasad projektowania obiektowego (dla zaawansowanych).

<?php
// ZLE - nieczytelne nazwy
$x = "Jan Kowalski";
$a = 25;
$arr = [];
// DOBRZE - opisowe nazwy
$userName = "Jan Kowalski";
$userAge = 25;
$orderItems = [];
// ZLE - skroty
$usrNm = "Jan";
$prc = 99.99;
// DOBRZE - pełne słowa
$userName = "Jan";
$price = 99.99;
ElementKonwencjaPrzykład
ZmiennecamelCase$userName, $orderTotal
FunkcjecamelCasegetUserById(), calculateTotal()
KlasyPascalCaseUserController, OrderService
StałeUPPER_SNAKEMAX_LOGIN_ATTEMPTS, DB_HOST
<?php
// ZLE - brak wciec, nieczytelne
function processOrder($order){
if($order->status=='pending'){
$total=$order->calculateTotal();
if($total>100){$order->applyDiscount(10);}
$order->save();
return true;}
return false;}
// DOBRZE - czytelne formatowanie
function processOrder(Order $order): bool
{
if ($order->status !== 'pending') {
return false;
}
$total = $order->calculateTotal();
if ($total > 100) {
$order->applyDiscount(10);
}
$order->save();
return true;
}
<?php
// ZLE - powtorzony kod
function getActiveUsers($pdo) {
$stmt = $pdo->prepare("SELECT * FROM users WHERE status = 'active'");
$stmt->execute();
return $stmt->fetchAll();
}
function getInactiveUsers($pdo) {
$stmt = $pdo->prepare("SELECT * FROM users WHERE status = 'inactive'");
$stmt->execute();
return $stmt->fetchAll();
}
function getPendingUsers($pdo) {
$stmt = $pdo->prepare("SELECT * FROM users WHERE status = 'pending'");
$stmt->execute();
return $stmt->fetchAll();
}
// DOBRZE - jedna funkcja z parametrem
function getUsersByStatus(PDO $pdo, string $status): array
{
$stmt = $pdo->prepare("SELECT * FROM users WHERE status = ?");
$stmt->execute([$status]);
return $stmt->fetchAll();
}
// Użycie
$activeUsers = getUsersByStatus($pdo, 'active');
$inactiveUsers = getUsersByStatus($pdo, 'inactive');
<?php
// ZLE - funkcja robi za dużo
function processUserRegistration($data) {
// Walidacja
if (empty($data['email'])) {
return ['error' => 'Email required'];
}
if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
return ['error' => 'Invalid email'];
}
if (strlen($data['password']) < 8) {
return ['error' => 'Password too short'];
}
// Zapis do bazy
$hash = password_hash($data['password'], PASSWORD_DEFAULT);
$stmt = $pdo->prepare("INSERT INTO users ...");
$stmt->execute([...]);
// Wysłanie e-maila
mail($data['email'], 'Welcome!', '...');
return ['success' => true];
}
// DOBRZE - podział na mniejsze funkcje
function validateUserData(array $data): ?string
{
if (empty($data['email'])) {
return 'Email wymagany';
}
if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
return 'Nieprawidłowy email';
}
if (strlen($data['password']) < 8) {
return 'Hasło za krótkie';
}
return null; // Brak błędów
}
function createUser(PDO $pdo, array $data): int
{
$hash = password_hash($data['password'], PASSWORD_DEFAULT);
$stmt = $pdo->prepare("INSERT INTO users (email, password) VALUES (?, ?)");
$stmt->execute([$data['email'], $hash]);
return $pdo->lastInsertId();
}
function sendWelcomeEmail(string $email): void
{
mail($email, 'Witamy!', 'Dziekujemy za rejestracje.');
}
// Użycie - czytelny przepływ
$error = validateUserData($data);
if ($error) {
return ['error' => $error];
}
$userId = createUser($pdo, $data);
sendWelcomeEmail($data['email']);
<?php
// ZLE - podatne na SQL Injection
$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
$result = $pdo->query($query);
// DOBRZE - prepared statement
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$_POST['username']]);
$user = $stmt->fetch();
<?php
// ZLE - podatne na XSS
echo "Witaj, " . $_GET['name'];
// DOBRZE - escapowanie
echo "Witaj, " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
<?php
// DOBRZE - walidacja przed użyciem
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
if (!$email) {
die('Nieprawidłowy email');
}
if ($age === false || $age < 0 || $age > 150) {
die('Nieprawidłowy wiek');
}
<?php
// ZLE - ukrywanie błędów
$result = @file_get_contents('plik.txt');
// ZLE - generyczne komunikaty
try {
// kod
} catch (Exception $e) {
echo "Błąd";
}
// DOBRZE - właściwa obsługa
try {
$content = file_get_contents('plik.txt');
if ($content === false) {
throw new RuntimeException('Nie można odczytać pliku');
}
} catch (RuntimeException $e) {
error_log($e->getMessage()); // Loguj błąd
echo "Przepraszamy, wystąpił problem."; // User-friendly komunikat
}
<?php
// ZLE - brak typow
function calculateDiscount($price, $percentage) {
return $price * ($percentage / 100);
}
// DOBRZE - typy i dokumentacja
/**
* Oblicza rabat od ceny
*
* @param float $price Cena produktu
* @param float $percentage Procent rabatu (0-100)
* @return float Wartość rabatu
*/
function calculateDiscount(float $price, float $percentage): float
{
if ($percentage < 0 || $percentage > 100) {
throw new InvalidArgumentException('Percentage must be 0-100');
}
return $price * ($percentage / 100);
}
<?php
// Nieczytelny, powtarzajacy się, niebezpieczny kod
$u = $_POST['u'];
$p = $_POST['p'];
$q = "SELECT * FROM users WHERE username='$u'";
$r = mysqli_query($conn, $q);
$row = mysqli_fetch_assoc($r);
if($row['password'] == $p) {
$_SESSION['logged'] = true;
$_SESSION['user'] = $row['username'];
header('Location: dashboard.php');
} else {
echo "Źle dane";
}
<?php
declare(strict_types=1);
function authenticateUser(PDO $pdo, string $username, string $password): ?array
{
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user || !password_verify($password, $user['password_hash'])) {
return null;
}
return $user;
}
function loginUser(array $user): void
{
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
}
// Użycie
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
$user = authenticateUser($pdo, $username, $password);
if ($user) {
loginUser($user);
header('Location: dashboard.php');
exit;
}
$error = 'Nieprawidłowy login lub hasło';
  • Uzywaj opisowych nazw zmiennych i funkcji
  • Przestrzegaj zasady DRY - nie powtarzaj kodu
  • Jedna funkcja = jedno zadanie
  • Zawsze uzywaj prepared statements (SQL)
  • Escapuj dane wyjsciowe (XSS)
  • Dodawaj type hints i return types
  • Obsługuj błędy właściwie
  • Formatuj kod konsekwentnie