PHP Backend - Server-Side Web Development

Comprehensive guide to PHP for backend web development. Learn server-side programming, database integration, security practices, and modern PHP frameworks for building robust web applications.


Introduction to PHP Backend Development

PHP is a popular server-side scripting language designed specifically for web development and can be embedded into HTML. It powers millions of websites and provides excellent database connectivity, making it ideal for backend development.

Basic PHP Syntax and Structure

PHP Tags and Output

<?php
// Opening tag
echo "Hello, World!";  // Display text
print "Hello again!";   // Alternative display function

// PHP closing tag - optional in pure PHP files
?>

Variables and Data Types

<?php
// Variables start with $
$name = "John";
$age = 30;
$height = 175.5;        // Float
$is_active = true;      // Boolean
$fruits = ["apple", "banana", "orange"];  // Array

// Constant (case-sensitive by default)
define("SITE_NAME", "My Website");
const PI = 3.14159;

// Variable variables
$var_name = "user";
$$var_name = "John";  // Creates $user = "John"

Control Structures

<?php
// Conditional statements
if ($age >= 18) {
    echo "Adult";
} elseif ($age >= 13) {
    echo "Teenager";
} else {
    echo "Child";
}

// Ternary operator
$status = ($is_active) ? "Active" : "Inactive";

// Switch statement
switch ($day) {
    case "Monday":
        echo "Start of work week";
        break;
    case "Friday":
        echo "TGIF!";
        break;
    default:
        echo "Regular day";
}

// Loops
for ($i = 0; $i < 5; $i++) {
    echo "Number: $i<br>";
}

foreach ($fruits as $fruit) {
    echo "Fruit: $fruit<br>";
}

$i = 0;
while ($i < 5) {
    echo "Count: $i<br>";
    $i++;
}

Functions and Classes

Function Definition and Usage

<?php
// Basic function
function greet($name) {
    return "Hello, $name!";
}

echo greet("Alice");

// Function with default parameter
function calculate_tax($amount, $rate = 0.1) {
    return $amount * $rate;
}

// Variable number of arguments
function sum(...$numbers) {
    return array_sum($numbers);
}

echo sum(1, 2, 3, 4, 5);  // 15

// Anonymous functions
$greet = function($name) {
    return "Hi, $name!";
};

Object-Oriented PHP

<?php
class User {
    // Properties
    public $name;
    private $email;
    protected $age;

    // Constructor
    public function __construct($name, $email, $age) {
        $this->name = $name;
        $this->email = $email;
        $this->age = $age;
    }

    // Methods
    public function getProfile() {
        return [
            'name' => $this->name,
            'email' => $this->email,
            'age' => $this->age
        ];
    }

    // Static method
    public static function validateEmail($email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }
}

// Usage
$user = new User("John Doe", "[email protected]", 30);
$profile = $user->getProfile();

// Static method call
$isValid = User::validateEmail("[email protected]");

Database Integration

MySQLi Extension

<?php
// Database connection
$servername = "localhost";
$username = "user";
$password = "password";
$dbname = "myapp";

$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// Prepared statement for security
$stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);

$name = "John Doe";
$email = "[email protected]";
$stmt->execute();

// Close connections
$stmt->close();
$conn->close();

PDO (PHP Data Objects)

<?php
try {
    // PDO connection with DSN
    $pdo = new PDO("mysql:host=localhost;dbname=myapp", "user", "password");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Prepared statement with named placeholders
    $stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
    $stmt->execute(['email' => '[email protected]']);

    $user = $stmt->fetch(PDO::FETCH_ASSOC);

    // Transaction example
    $pdo->beginTransaction();

    $pdo->exec("INSERT INTO logs (action, user_id) VALUES ('login', 1)");
    $pdo->exec("UPDATE users SET last_login = NOW() WHERE id = 1");

    $pdo->commit();

} catch (PDOException $e) {
    $pdo->rollback();
    echo "Error: " . $e->getMessage();
}

File Handling and Uploads

File Operations

<?php
// Reading files
$content = file_get_contents("data.txt");
$lines = file("data.txt");  // Returns array of lines

// Writing files
file_put_contents("output.txt", "Hello World!");

// Append to file
file_put_contents("log.txt", "New entry\n", FILE_APPEND);

// Check if file exists
if (file_exists("test.txt")) {
    echo "File exists";
}

// Get file info
$file_size = filesize("data.txt");
$file_info = pathinfo("data.txt");

File Upload Handling

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $target_dir = "uploads/";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);

    // Check if file already exists
    if (file_exists($target_file)) {
        echo "Sorry, file already exists.";
        exit;
    }

    // Check file size (5MB limit)
    if ($_FILES["fileToUpload"]["size"] > 5000000) {
        echo "Sorry, your file is too large.";
        exit;
    }

    // Allow certain file formats
    $allowed_types = ["jpg", "png", "jpeg", "gif", "pdf"];
    $file_extension = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));

    if (!in_array($file_extension, $allowed_types)) {
        echo "Sorry, only JPG, JPEG, PNG, GIF & PDF files are allowed.";
        exit;
    }

    // Upload file
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        echo "The file " . basename($_FILES["fileToUpload"]["name"]) . " has been uploaded.";
    } else {
        echo "Sorry, there was an error uploading your file.";
    }
}

Sessions and Authentication

Session Management

<?php
// Start session
session_start();

// Store session data
$_SESSION['user_id'] = 123;
$_SESSION['username'] = 'john_doe';

// Retrieve session data
$user_id = $_SESSION['user_id'];
$username = $_SESSION['username'];

// Check if user is logged in
if (isset($_SESSION['user_id'])) {
    echo "Welcome back, " . $_SESSION['username'];
}

// Destroy session (logout)
session_destroy();

User Authentication System

<?php
class Auth {
    private $pdo;

    public function __construct($pdo) {
        $this->pdo = $pdo;
    }

    public function login($email, $password) {
        $stmt = $this->pdo->prepare("SELECT id, password FROM users WHERE email = ?");
        $stmt->execute([$email]);
        $user = $stmt->fetch();

        if ($user && password_verify($password, $user['password'])) {
            $_SESSION['user_id'] = $user['id'];
            return true;
        }
        return false;
    }

    public function logout() {
        session_destroy();
    }

    public function isLoggedIn() {
        return isset($_SESSION['user_id']);
    }

    public function register($name, $email, $password) {
        $hashed_password = password_hash($password, PASSWORD_DEFAULT);

        $stmt = $this->pdo->prepare("INSERT INTO users (name, email, password) VALUES (?, ?, ?)");
        return $stmt->execute([$name, $email, $hashed_password]);
    }
}

Security Best Practices

Input Validation and Sanitization

<?php
// Sanitize user input
$name = filter_var($_POST['name'], FILTER_SANITIZE_STRING);
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);

// Validate email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "Invalid email format";
}

// Validate numeric input
$age = filter_var($_POST['age'], FILTER_VALIDATE_INT, [
    "options" => ["min_range" => 1, "max_range" => 120]
]);

if ($age === false) {
    echo "Invalid age";
}

Preventing SQL Injection

<?php
// Use prepared statements to prevent SQL injection
$stmt = $pdo->prepare("SELECT * FROM users WHERE name LIKE ?");
$search_term = "%" . $_GET['search'] . "%";  // User input
$stmt->execute([$search_term]);
$results = $stmt->fetchAll();

Password Security

<?php
// Hash passwords before storing
$password = $_POST['password'];
$hashed_password = password_hash($password, PASSWORD_DEFAULT);

// Verify passwords
$user_input = $_POST['password'];
$stored_hash = $user['password_hash'];

if (password_verify($user_input, $stored_hash)) {
    // Password correct
}

// Rehash if needed (algorithm improvement)
if (password_needs_rehash($stored_hash, PASSWORD_DEFAULT)) {
    $new_hash = password_hash($user_input, PASSWORD_DEFAULT);
    // Update database with $new_hash
}

Cross-Site Scripting (XSS) Prevention

<?php
// Don't do this - vulnerable to XSS
echo "<h1>Welcome " . $_GET['name'] . "</h1>";

// Safe way: escape output
echo "<h1>Welcome " . htmlspecialchars($_GET['name']) . "</h1>";

// Using short echo tags (PHP 7+)
$sanitized_input = htmlspecialchars($_GET['input'] ?? '', ENT_QUOTES, 'UTF-8');
?>

<h1><?=$sanitized_input?></h1>

Frameworks and Modern PHP

Laravel Framework

# Install Laravel
composer create-project laravel/laravel my-app
// Laravel route definition
Route::get('/users', function () {
    $users = DB::table('users')->get();
    return view('users.index', compact('users'));
});

// Laravel Eloquent Model
class User extends Model
{
    protected $fillable = ['name', 'email', 'password'];

    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

// API Resource
class UserResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at,
        ];
    }
}

Symfony Framework

# Symfony route configuration
# config/routes.yaml
users_list:
    path: /users
    controller: App\Controller\UserController::list
// Symfony Controller
class UserController extends AbstractController
{
    #[Route('/users/{id}', name: 'user_show')]
    public function show(User $user): Response
    {
        return $this->render('user/show.html.twig', [
            'user' => $user,
        ]);
    }
}