// Complete Reference Guide

PHP Zero
to Hero

A structured, beginner-friendly guide covering procedural PHP and MySQLi from the ground up — no frameworks, no magic, just clear fundamentals.

Introduction to PHP

PHP is a server-side scripting language designed for web development. It powers over 75% of all websites that use a server-side language, including WordPress, Facebook (historically), and Wikipedia.

What Is PHP?

PHP (recursive: PHP: Hypertext Preprocessor) is an open-source, general-purpose scripting language especially suited for web development. It runs on the server and generates HTML that is sent to the browser.

FeatureDetail
TypeInterpreted, server-side scripting language
File Extension.php
Current VersionPHP 8.x
LicenseOpen Source (PHP License)
Runs OnLinux, Windows, macOS

How PHP Works — The Client-Server Model

Understanding this cycle is critical for every PHP developer:

  1. User types a URL into the browser and presses Enter.
  2. Browser sends an HTTP request to the web server.
  3. Web server detects a .php file and passes it to the PHP interpreter.
  4. PHP executes the code — connects to databases, processes logic, etc.
  5. PHP returns pure HTML to the web server.
  6. Web server sends the HTML response to the browser.
  7. Browser renders the page. The user sees no PHP code, ever.
Key Insight PHP code lives on the server. The browser only ever receives the final HTML output. This is why PHP is called a "server-side" language.

Environment Setup

To run PHP on your local machine, you need a web server (Apache), PHP interpreter, and MySQL database. All-in-one packages make this trivial.

Recommended Tools

ToolOSLink
XAMPP RecommendedWindows, macOS, Linuxapachefriends.org
WAMPWindowswampserver.com
LAMPLinuxBuilt-in packages
LaragonWindowslaragon.org

XAMPP Quick Start

  1. Download XAMPP from apachefriends.org and install it.
  2. Open the XAMPP Control Panel and start Apache and MySQL.
  3. Navigate to C:\xampp\htdocs\ (Windows) or /opt/lampp/htdocs/ (Linux).
  4. Create a folder, e.g. myphpapp, and place your .php files there.
  5. Open a browser and visit http://localhost/myphpapp/index.php.

Your First PHP File

PHP<!-- File: htdocs/myphpapp/index.php -->
<?php
    // This is your first PHP script
    echo "<h1>Hello, PHP World!</h1>";
    echo "<p>PHP version: " . phpversion() . "</p>";
?>

PHP Basics

The building blocks: syntax, variables, data types, operators, and control structures.

Syntax and Structure

PHP code is embedded inside <?php ... ?> tags. Every statement ends with a semicolon ;.

PHP<?php
    // Single-line comment
    /* Multi-line
       comment */

    echo "This prints text to the page.";    // semicolon required
    print "print also outputs text.";

    // Mixing PHP with HTML
?>
<p>This is plain HTML.</p>
<?php
    echo "Back in PHP.";
?>

Variables and Data Types

Variables start with $. PHP is loosely typed — you don't declare types.

PHP<?php
    // String
    $name     = "Alice";

    // Integer
    $age      = 25;

    // Float
    $price    = 19.99;

    // Boolean
    $isActive = true;

    // NULL
    $nothing  = null;

    // Check data type
    echo gettype($age);         // outputs: integer
    echo var_dump($isActive);   // outputs: bool(true)

    // String interpolation (double quotes only)
    echo "Hello, $name! You are $age years old.";

    // String concatenation
    echo "Hello, " . $name . "!";
?>

Operators

PHP<?php
    // Arithmetic
    $a = 10; $b = 3;
    echo $a + $b;   // 13
    echo $a - $b;   // 7
    echo $a * $b;   // 30
    echo $a / $b;   // 3.333...
    echo $a % $b;   // 1 (modulo)
    echo $a ** $b;  // 1000 (power)

    // Comparison
    var_dump(5 == "5");   // true  (loose comparison)
    var_dump(5 === "5");  // false (strict: type + value)
    var_dump(5 != 3);    // true
    var_dump(5 > 3);     // true

    // Logical
    var_dump(true && false);  // false
    var_dump(true || false);  // true
    var_dump(!true);           // false

    // Assignment shortcuts
    $x = 10;
    $x += 5;   // $x = 15
    $x -= 3;   // $x = 12
    $x++;       // $x = 13
    $x--;       // $x = 12
?>

Control Structures

PHP<?php
    // ── if / else if / else ──────────────────────
    $score = 75;

    if ($score >= 90) {
        echo "Grade: A";
    } elseif ($score >= 75) {
        echo "Grade: B";
    } elseif ($score >= 60) {
        echo "Grade: C";
    } else {
        echo "Grade: F";
    }

    // ── switch ───────────────────────────────────
    $day = "Monday";

    switch ($day) {
        case "Monday":
            echo "Start of the work week.";
            break;
        case "Friday":
            echo "Almost the weekend!";
            break;
        default:
            echo "Regular day.";
    }

    // ── for loop ─────────────────────────────────
    for ($i = 1; $i <= 5; $i++) {
        echo "Count: $i<br>";
    }

    // ── while loop ───────────────────────────────
    $n = 1;
    while ($n <= 5) {
        echo "Number: $n<br>";
        $n++;
    }

    // ── foreach loop (for arrays) ────────────────
    $colors = ["red", "green", "blue"];
    foreach ($colors as $color) {
        echo "Color: $color<br>";
    }
?>

Functions & Arrays

Functions let you reuse code. Arrays let you store multiple values in one variable.

Creating and Using Functions

PHP<?php
    // Basic function — no parameters
    function greet() {
        echo "Hello, World!";
    }
    greet();  // call the function

    // Function with parameters
    function greetUser($name) {
        echo "Hello, $name!";
    }
    greetUser("Alice");

    // Function with default parameter value
    function greetWithTitle($name, $title = "Mr.") {
        echo "Hello, $title $name!";
    }
    greetWithTitle("Smith");           // Hello, Mr. Smith!
    greetWithTitle("Jones", "Dr.");    // Hello, Dr. Jones!

    // Function with return value
    function add($a, $b) {
        return $a + $b;
    }
    $result = add(5, 3);
    echo "Sum: $result";   // Sum: 8

    // Useful built-in string functions
    $str = "  Hello PHP!  ";
    echo strlen($str);           // length
    echo strtoupper($str);      // HELLO PHP!
    echo strtolower($str);      // hello php!
    echo trim($str);            // removes whitespace
    echo str_replace("PHP", "World", $str);  // Hello World!
?>

Arrays

PHP<?php
    // ── Indexed Array ────────────────────────────
    $fruits = ["Apple", "Banana", "Cherry"];
    echo $fruits[0];         // Apple (index starts at 0)
    echo count($fruits);    // 3

    // Add to array
    $fruits[] = "Mango";    // appends at end

    // Loop through indexed array
    foreach ($fruits as $fruit) {
        echo $fruit . "<br>";
    }

    // ── Associative Array ────────────────────────
    $student = [
        "name"  => "Alice",
        "age"   => 22,
        "grade" => "A"
    ];
    echo $student["name"];    // Alice
    $student["age"] = 23;    // update value

    // Loop associative array (key => value)
    foreach ($student as $key => $value) {
        echo "$key: $value<br>";
    }

    // ── Multidimensional Array ───────────────────
    $students = [
        ["name" => "Alice", "grade" => "A"],
        ["name" => "Bob",   "grade" => "B"],
        ["name" => "Carol", "grade" => "A"]
    ];

    foreach ($students as $s) {
        echo $s["name"] . " — Grade: " . $s["grade"] . "<br>";
    }

    // Useful array functions
    $nums = [3, 1, 4, 1, 5, 9];
    sort($nums);                     // sort ascending
    echo in_array(4, $nums);         // true — check if exists
    echo array_push($nums, 10);     // add to end
    echo implode(", ", $nums);      // join into string
?>

Forms & User Input

HTML forms are the primary way users send data to PHP. Data arrives via $_GET or $_POST superglobals.

HTML Form + PHP Handler

HTML / PHP<!-- form.html -->
<form action="process.php" method="post">
    <label>Name: <input type="text" name="username"></label><br>
    <label>Email: <input type="email" name="email"></label><br>
    <input type="submit" value="Submit">
</form>
PHP<?php
// process.php — receives the form data

if ($_SERVER["REQUEST_METHOD"] == "POST") {

    // Retrieve POST data
    $username = $_POST["username"];
    $email    = $_POST["email"];

    // Basic validation
    if (empty($username) || empty($email)) {
        echo "Error: All fields are required.";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        echo "Error: Invalid email format.";
    } else {
        // Sanitize to remove unwanted HTML tags
        $username = htmlspecialchars(strip_tags($username));
        $email    = htmlspecialchars(strip_tags($email));

        echo "Welcome, $username! Your email is $email.";
    }
}
?>

GET vs POST

FeatureGETPOST
VisibilityData shown in URLData hidden in request body
Max size~2048 charsNo practical limit
CachingCan be cached/bookmarkedNot cached
Use forSearch queries, filtersPasswords, forms, file uploads
Example?name=Alice&age=25Body of HTTP request

Working with MySQL — MySQLi Procedural

MySQLi (MySQL Improved) is the PHP extension for connecting to MySQL databases. We use the procedural style throughout this guide.

Connecting to the Database

PHP<?php
// db_connect.php — reusable connection file

$host   = "localhost";
$user   = "root";
$pass   = "";          // empty in XAMPP by default
$dbname = "school_db";

// Create connection
$conn = mysqli_connect($host, $user, $pass, $dbname);

// Check connection
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}

echo "Connected to MySQL successfully!";
?>

Creating the Database and Table

Run these SQL commands in phpMyAdmin, or execute them via PHP:

SQL-- Run in phpMyAdmin or via PHP
CREATE DATABASE IF NOT EXISTS school_db;

USE school_db;

CREATE TABLE IF NOT EXISTS students (
    id       INT AUTO_INCREMENT PRIMARY KEY,
    name     VARCHAR(100) NOT NULL,
    email    VARCHAR(150) NOT NULL UNIQUE,
    course   VARCHAR(100),
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

CRUD Operations

Create, Read, Update, Delete — the four fundamental database operations.

⚠️ Educational Note — SQL Injection Risk The examples below insert variables directly into SQL strings. This is intentionally simple for learning purposes. In a real production application, you must use prepared statements or strictly sanitize all input. See the Security chapter at the end of this guide for full details.

INSERT — Add a New Record

PHP<?php
include "db_connect.php";

// Data to insert (from a form, for example)
$name   = "Alice Johnson";
$email  = "alice@example.com";
$course = "Computer Science";

// Build the SQL query string
$sql = "INSERT INTO students (name, email, course)
        VALUES ('$name', '$email', '$course')";

// Execute query
if (mysqli_query($conn, $sql)) {
    $newId = mysqli_insert_id($conn);  // get ID of inserted row
    echo "Student added! ID = $newId";
} else {
    echo "Error: " . mysqli_error($conn);
}

mysqli_close($conn);
?>

SELECT — Read Records

PHP<?php
include "db_connect.php";

// Select all students
$sql    = "SELECT * FROM students ORDER BY id DESC";
$result = mysqli_query($conn, $sql);

if (mysqli_num_rows($result) > 0) {

    echo "<table border='1'>";
    echo "<tr><th>ID</th><th>Name</th><th>Email</th><th>Course</th></tr>";

    // Fetch each row as an associative array
    while ($row = mysqli_fetch_assoc($result)) {
        echo "<tr>";
        echo   "<td>" . $row["id"]     . "</td>";
        echo   "<td>" . $row["name"]   . "</td>";
        echo   "<td>" . $row["email"]  . "</td>";
        echo   "<td>" . $row["course"] . "</td>";
        echo "</tr>";
    }
    echo "</table>";

} else {
    echo "No students found.";
}

// Select a single student by ID
$id     = 1;
$sql    = "SELECT * FROM students WHERE id = $id";
$result = mysqli_query($conn, $sql);
$row    = mysqli_fetch_assoc($result);
echo "Name: " . $row["name"];

mysqli_close($conn);
?>

UPDATE — Modify a Record

PHP<?php
include "db_connect.php";

$id     = 1;
$name   = "Alice Smith";
$course = "Data Science";

$sql = "UPDATE students
        SET name = '$name', course = '$course'
        WHERE id = $id";

if (mysqli_query($conn, $sql)) {
    $affected = mysqli_affected_rows($conn);
    echo "Record updated. Rows affected: $affected";
} else {
    echo "Update failed: " . mysqli_error($conn);
}

mysqli_close($conn);
?>

DELETE — Remove a Record

PHP<?php
include "db_connect.php";

$id  = 1;
$sql = "DELETE FROM students WHERE id = $id";

if (mysqli_query($conn, $sql)) {
    echo "Student deleted successfully.";
} else {
    echo "Delete failed: " . mysqli_error($conn);
}

mysqli_close($conn);
?>

Key MySQLi Functions Reference

FunctionPurpose
mysqli_connect()Open a new connection to the MySQL server
mysqli_query()Execute a query on the database
mysqli_fetch_assoc()Fetch row as an associative array
mysqli_fetch_array()Fetch row as both associative and numeric array
mysqli_num_rows()Number of rows in a result set
mysqli_affected_rows()Rows affected by last INSERT/UPDATE/DELETE
mysqli_insert_id()Auto-generated ID of last INSERT
mysqli_error()Error message for the last operation
mysqli_connect_error()Error message for the connection attempt
mysqli_real_escape_string()Escape special characters for use in SQL
mysqli_close()Close the database connection

Sessions & Cookies

HTTP is stateless. Sessions and cookies allow PHP to "remember" users across multiple page requests.

Sessions

Sessions store data on the server. A session ID cookie is sent to the browser to identify the user.

PHP<?php
// MUST call session_start() at the very top of every page that uses sessions
session_start();

// Store data in session
$_SESSION["username"]  = "Alice";
$_SESSION["user_id"]   = 42;
$_SESSION["logged_in"] = true;

// Read session data
if (isset($_SESSION["logged_in"]) && $_SESSION["logged_in"]) {
    echo "Welcome back, " . $_SESSION["username"] . "!";
} else {
    echo "Please log in.";
}

// Delete a single session variable
unset($_SESSION["username"]);

// Destroy entire session (logout)
session_unset();
session_destroy();
echo "You have been logged out.";
?>

Simple Login System Using Sessions

PHP<?php
// login.php
session_start();
include "db_connect.php";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $username = mysqli_real_escape_string($conn, $_POST["username"]);
    $password = mysqli_real_escape_string($conn, $_POST["password"]);

    $sql    = "SELECT * FROM users WHERE username = '$username' LIMIT 1";
    $result = mysqli_query($conn, $sql);

    if (mysqli_num_rows($result) == 1) {
        $user = mysqli_fetch_assoc($result);

        // Verify hashed password (passwords should always be hashed!)
        if (password_verify($password, $user["password"])) {
            $_SESSION["user_id"]   = $user["id"];
            $_SESSION["username"]  = $user["username"];
            $_SESSION["logged_in"] = true;
            header("Location: dashboard.php");
            exit();
        }
    }
    echo "Invalid username or password.";
}
?>

Cookies

Cookies store data in the browser. They persist beyond the session and can be read on subsequent visits.

PHP<?php
// Set a cookie — expires in 7 days
setcookie("theme", "dark", time() + (7 * 24 * 60 * 60), "/");
//        name      value   expiry (seconds from now)           path

// Read a cookie
if (isset($_COOKIE["theme"])) {
    $theme = $_COOKIE["theme"];
    echo "Current theme: $theme";
}

// Delete a cookie by setting expiry in the past
setcookie("theme", "", time() - 3600, "/");
?>

File Handling

PHP can read, write, and manipulate files on the server. It also supports handling file uploads from HTML forms.

Reading and Writing Files

PHP<?php
// ── Write to a file (creates if not exists) ──
$file = "notes.txt";
file_put_contents($file, "Hello, this is a note!\n");

// Append to file without overwriting
file_put_contents($file, "Second line.\n", FILE_APPEND);

// ── Read entire file ─────────────────────────
$content = file_get_contents($file);
echo $content;

// ── Read line by line (large files) ──────────
$handle = fopen($file, "r");   // "r" = read mode
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        echo $line . "<br>";
    }
    fclose($handle);
}

// ── Check file exists ─────────────────────────
if (file_exists($file)) {
    echo "File size: " . filesize($file) . " bytes";
}

// ── Delete a file ─────────────────────────────
unlink($file);
?>

File Upload

HTML / PHP<!-- upload_form.html -->
<form action="upload.php" method="post" enctype="multipart/form-data">
    <label>Select file: <input type="file" name="userfile"></label>
    <input type="submit" value="Upload">
</form>
PHP<?php
// upload.php

$uploadDir  = "uploads/";
$allowedTypes = ["image/jpeg", "image/png", "image/gif"];
$maxSize    = 2 * 1024 * 1024;  // 2 MB

if (isset($_FILES["userfile"])) {
    $file     = $_FILES["userfile"];
    $fileName = basename($file["name"]);
    $fileType = $file["type"];
    $fileSize = $file["size"];
    $tmpPath  = $file["tmp_name"];

    // Validate type and size
    if (!in_array($fileType, $allowedTypes)) {
        die("Error: Only JPEG, PNG, GIF allowed.");
    }
    if ($fileSize > $maxSize) {
        die("Error: File exceeds 2 MB limit.");
    }

    // Generate unique name to prevent overwriting
    $uniqueName = uniqid() . "_" . $fileName;
    $destPath   = $uploadDir . $uniqueName;

    if (move_uploaded_file($tmpPath, $destPath)) {
        echo "File uploaded: <img src='$destPath' width='200'>";
    } else {
        echo "Upload failed.";
    }
}
?>

Mini Project — Student Management System

Putting it all together: a complete, working CRUD application with form handling, MySQL storage, and session-protected pages.

Project Structure

FILE TREEstudent_manager/
├── db_connect.php      ← Database connection
├── index.php           ← List all students
├── add_student.php     ← Form + INSERT handler
├── edit_student.php    ← Form + UPDATE handler
└── delete_student.php  ← DELETE handler

db_connect.php

PHP<?php
$conn = mysqli_connect("localhost", "root", "", "school_db");
if (!$conn) {
    die("DB Error: " . mysqli_connect_error());
}
?>

index.php — List All Students

PHP<?php
include "db_connect.php";
$result = mysqli_query($conn, "SELECT * FROM students ORDER BY id DESC");
?>
<!DOCTYPE html>
<html><head><title>Students</title></head><body>
<h1>Student Management</h1>
<a href="add_student.php">+ Add Student</a>
<table border="1" cellpadding="8">
  <tr><th>ID</th><th>Name</th><th>Email</th><th>Course</th><th>Actions</th></tr>
<?php
while ($row = mysqli_fetch_assoc($result)):
?>
  <tr>
    <td><?= $row["id"] ?></td>
    <td><?= $row["name"] ?></td>
    <td><?= $row["email"] ?></td>
    <td><?= $row["course"] ?></td>
    <td>
      <a href="edit_student.php?id=<?= $row["id"] ?>">Edit</a> |
      <a href="delete_student.php?id=<?= $row["id"] ?>"
         onclick="return confirm('Delete this student?')">Delete</a>
    </td>
  </tr>
<?php endwhile; ?>
</table>
</body></html>

add_student.php — Form + INSERT

PHP<?php
include "db_connect.php";

$error = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $name   = mysqli_real_escape_string($conn, trim($_POST["name"]));
    $email  = mysqli_real_escape_string($conn, trim($_POST["email"]));
    $course = mysqli_real_escape_string($conn, trim($_POST["course"]));

    if (empty($name) || empty($email)) {
        $error = "Name and email are required.";
    } else {
        $sql = "INSERT INTO students (name, email, course)
                VALUES ('$name', '$email', '$course')";
        if (mysqli_query($conn, $sql)) {
            header("Location: index.php");
            exit();
        } else {
            $error = "Insert failed: " . mysqli_error($conn);
        }
    }
}
?>
<!DOCTYPE html>
<html><head><title>Add Student</title></head><body>
<h2>Add New Student</h2>
<?php if ($error) echo "<p style='color:red'>$error</p>"; ?>
<form method="post">
  <label>Name:   <input type="text"  name="name"   required></label><br><br>
  <label>Email:  <input type="email" name="email"  required></label><br><br>
  <label>Course: <input type="text"  name="course"></label><br><br>
  <input type="submit" value="Add Student">
  <a href="index.php">Cancel</a>
</form>
</body></html>

edit_student.php — Fetch + UPDATE

PHP<?php
include "db_connect.php";

$id = (int)$_GET["id"];   // cast to integer for safety

// Handle UPDATE
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $name   = mysqli_real_escape_string($conn, trim($_POST["name"]));
    $email  = mysqli_real_escape_string($conn, trim($_POST["email"]));
    $course = mysqli_real_escape_string($conn, trim($_POST["course"]));
    $sql    = "UPDATE students SET name='$name', email='$email',
              course='$course' WHERE id=$id";
    mysqli_query($conn, $sql);
    header("Location: index.php");
    exit();
}

// Fetch current data
$result = mysqli_query($conn, "SELECT * FROM students WHERE id = $id");
$row    = mysqli_fetch_assoc($result);
?>
<!DOCTYPE html>
<html><head><title>Edit Student</title></head><body>
<h2>Edit Student</h2>
<form method="post">
  Name:   <input type="text"  name="name"   value="<?= htmlspecialchars($row["name"]) ?>"><br>
  Email:  <input type="email" name="email"  value="<?= htmlspecialchars($row["email"]) ?>"><br>
  Course: <input type="text"  name="course" value="<?= htmlspecialchars($row["course"]) ?>"><br>
  <input type="submit" value="Save Changes">
  <a href="index.php">Cancel</a>
</form>
</body></html>

delete_student.php

PHP<?php
include "db_connect.php";

$id = (int)$_GET["id"];   // integer cast prevents injection
mysqli_query($conn, "DELETE FROM students WHERE id = $id");
header("Location: index.php");
exit();
?>

Security Notes — SQL Injection & Best Practices

This is the most critical chapter. Please read it carefully before deploying any PHP application.

What is SQL Injection?

SQL Injection is an attack where a malicious user inserts SQL code into a form field or URL parameter, tricking your database into executing unintended commands.

⚠️ Dangerous Example — DO NOT USE IN PRODUCTION The code below is intentionally vulnerable to illustrate the problem.
PHP — VULNERABLE ❌<?php
// User enters: ' OR '1'='1 in the username field
$username = $_POST["username"];   // NO sanitization!

$sql = "SELECT * FROM users WHERE username = '$username'";
// Actual query becomes:
// SELECT * FROM users WHERE username = '' OR '1'='1'
// This returns ALL users — attacker is now logged in!
?>

Defence Strategy 1: mysqli_real_escape_string()

This function escapes special characters before inserting them into a query. It is the minimum you should always do in this guide's style.

PHP — BETTER ✓<?php
// Escape ALL user input before using in SQL
$username = mysqli_real_escape_string($conn, $_POST["username"]);
$sql      = "SELECT * FROM users WHERE username = '$username'";
?>

Defence Strategy 2: Integer Casting

For numeric IDs from URLs, always cast to integer:

PHP<?php
// Safe — any non-integer becomes 0
$id = (int)$_GET["id"];
$sql = "SELECT * FROM students WHERE id = $id";
?>
✅ Why Prepared Statements Are Better (Real-World Advice) The examples in this guide use direct string interpolation for educational clarity. In a real production application, you should always use prepared statements with parameter binding. Prepared statements separate SQL code from data entirely — it's architecturally impossible for user data to be interpreted as SQL, regardless of what characters it contains. mysqli_real_escape_string() helps but has edge cases and relies on correct character encoding.

Other Essential Security Practices

PracticeWhy It MattersHow
Hash passwordsNever store plain-text passwordspassword_hash() & password_verify()
Sanitize outputPrevent XSS attackshtmlspecialchars() when echoing user data
Validate inputReject bad data earlyfilter_var(), empty(), type checks
Use HTTPSEncrypt data in transitSSL certificate on your server
Limit DB privilegesContain damage if compromisedDon't use root; create limited DB users
Error reporting (dev only)Don't expose errors in productiondisplay_errors = Off in php.ini for production
Regenerate session IDPrevent session fixationsession_regenerate_id(true) after login