PHP Best Practices

This page is a wrap-up checklist for everything covered in this PHP tutorial: security, code organization, error handling, performance, database access, sessions/cookies, and a few general habits worth carrying into every project you build.

1) Security Recap

Never trust input, and never trust what goes back out either. See PHP Security and Form Validation for the full walkthrough.

<?php
  // Escape output to prevent XSS
  echo htmlspecialchars($comment, ENT_QUOTES, 'UTF-8');

  // Hash passwords - never store plain text
  $hash = password_hash($password, PASSWORD_DEFAULT);
?>
  • Always escape output with htmlspecialchars() before printing user data.
  • Always use prepared statements for SQL — never concatenate raw input into a query.
  • Hash passwords with password_hash(); verify with password_verify().
  • Validate everything server-side, even if it was already validated in JavaScript.

2) Code Organization

Keep logic and presentation apart so pages stay readable as they grow. See Includes.

<?php
  // header.php, footer.php, sidebar.php kept separate and reused
  include_once('php-header.php');

  // Business logic in a function, not mixed into the markup
  function calculateDiscount(float $price, float $percent): float {
    return $price - ($price * $percent / 100);
  }
?>
  • Separate logic (functions, classes) from presentation (HTML output).
  • Reuse header/sidebar/footer with include_once instead of copy-pasting markup.
  • Use meaningful, descriptive names for variables and functions.

3) Error Handling

Never show raw errors to visitors in production. Full details on PHP Error Handling.

<?php
  // Production settings
  ini_set('display_errors', '0');
  ini_set('log_errors', '1');
  ini_set('error_log', '/var/log/php/app-errors.log');
?>
  • Turn display_errors off and log_errors on in production.
  • Wrap risky operations in try/catch and use custom exception classes where useful.
  • Log enough detail (message, file, line) to debug later without exposing it to users.

4) Performance

Small habits keep pages fast as data grows.

<?php
  // Bad: one query per loop iteration (N+1 problem)
  foreach ($userIds as $id) {
    $stmt = $pdo->query("SELECT * FROM users WHERE id={$id}");
  }

  // Good: fetch everything needed in one query, outside the loop
  $stmt = $pdo->prepare('SELECT * FROM users WHERE id IN (?)');
?>
  • Avoid running database queries inside loops — fetch what you need in one query.
  • Cache results that don't change often (config, lookups) instead of recomputing them.
  • Close database connections/free result sets when a script no longer needs them.

5) Database Access

See PHP & MySQL for the full connection and query walkthrough.

<?php
  $stmt = $pdo->prepare('SELECT id, title FROM posts ORDER BY id DESC LIMIT ?');
  $stmt->execute([20]);
  $posts = $stmt->fetchAll();
?>
  • Always use prepared statements — never build SQL with string concatenation.
  • Use LIMIT when reading from large tables instead of loading everything.
  • Index columns you filter or sort on frequently.

6) Sessions & Cookies

See Sessions and Cookies for details.

<?php
  session_start();

  // After a successful login, always regenerate the session ID
  session_regenerate_id(true);
  $_SESSION['user_id'] = $user['id'];

  // Cookies: reasonable expiry, not "never expires"
  setcookie('remember_me', '1', time() + 86400 * 7);
?>
  • Call session_regenerate_id() right after login to prevent session fixation.
  • Set a reasonable cookie expiry — avoid cookies that never expire.
  • Mark sensitive cookies HttpOnly and Secure where possible.

7) General Habits

A few habits that pay off across every project.

<?php
  // This site's own php-forms.php starts with exactly this line
  declare(strict_types=1);
?>
  • Keep your PHP version updated to receive security and performance fixes.
  • Use declare(strict_types=1) so type hints are enforced strictly — this tutorial's own php-forms.php page opens with this exact line.
  • Read the changelog before upgrading — see What's New in PHP 8.
AreaOne-line rule
SecurityEscape output, prepare queries, hash passwords, validate server-side.
OrganizationSplit logic from markup; reuse includes and functions.
Error handlingLog in production, never display raw errors to users.
PerformanceNo queries inside loops; cache and close what you don't need open.
DatabasePrepared statements always; LIMIT on large tables.
Sessions/cookiesRegenerate session ID after login; set sane cookie expiry.
GeneralStay updated; use strict_types for safer code.
Congratulations! You've completed the PHP tutorial — from syntax and variables all the way through forms, sessions, security, error handling, and PHP 8 features. Click Next below to carry that momentum into the Python tutorial.