Lecture 1 / 12
Lecture 01 · Fundamentals

Introduction to PHP & Setup

Beginner ~45 min

What is PHP?

PHP (Hypertext Preprocessor) is a powerful, general-purpose scripting language that is executed on the server. Unlike HTML or JavaScript (which run in your browser), PHP code is processed by the server before the page is even sent to the user.

It is the backbone of the modern web, powering over 75% of all websites, including giants like WordPress, Facebook, and Wikipedia. Its primary strength is its ability to interact with databases and generate dynamic page content on the fly.

How Server-Side Scripting Works

To understand PHP, you must understand the difference between the Client and the Server:

  • Client-Side (Frontend): HTML, CSS, and JS run in the user's browser. The user can see this code using "Inspect Element."
  • Server-Side (Backend): PHP runs on the web server. The server executes the PHP code and sends only the resulting HTML to the browser. The user never sees the actual PHP source code.

Why PHP?

  • Easy to Learn: It has a friendly syntax for beginners and a massive community for support.
  • Database Power: PHP has native, high-performance support for MySQL, PostgreSQL, and MariaDB.
  • Massive Ecosystem: From the CMS giant WordPress to professional frameworks like Laravel and Symfony.
  • Cross-Platform: Runs on Windows, Linux, and macOS.

Installation & Setup

Because PHP is a server-side language, you cannot just open a .php file in your browser like you do with an .html file. You need a local server environment.

Recommended Tool: XAMPP (available for Windows, Mac, and Linux). XAMPP installs everything you need in one click: Apache (The Server), MySQL (The Database), and PHP.

The "htdocs" Rule (Crucial!)

For your PHP code to run, it must be placed in a specific folder where the Apache server can find it:

  • Install XAMPP $\rightarrow$ Open the XAMPP Control Panel $\rightarrow$ Start Apache.
  • Navigate to the C:\xampp\htdocs folder (on Windows) or /Applications/XAMPP/htdocs (on Mac).
  • Create a new folder for your project (e.g., php_mastery) inside htdocs.
  • Access your files in the browser via: localhost/php_mastery/filename.php.

Your First PHP Program

PHP code is embedded inside special tags. Any text outside these tags is treated as regular HTML.

hello.php
<?php
// This is a PHP comment
echo ("Hello, PHP Mastery!"); 
echo (" Modern, safe, and fun!");
?>
Output
Hello, PHP Mastery! Modern, safe, and fun!

Breaking Down the Syntax

  • <?php ... ?>: These are the PHP delimiters. Everything inside these tags is processed by the server.
  • echo: The most common way to output text to the browser.
  • ; (Semicolon): Every single PHP statement must end with a semicolon. Forgetting this is the #1 cause of errors for beginners.
  • //: Used for single-line comments.

💻 Try It Yourself - Multi-Language Compiler

Practice PHP and many other programming languages right here in your browser! Switch between languages, modify the code, and click "Run" to see results instantly.

💡 Practice Tips:

  • Switch to PHP in the language selector and try the web development examples
  • Experiment with PHP's dynamic typing and array functions
  • Try other web languages like JavaScript, TypeScript, or Python to compare syntax
  • Use the "Load Example" button to see PHP-specific code samples
  • Use Ctrl+Enter to quickly run your code

Testing Your Setup

To verify that PHP is installed and working correctly, create a file called info.php with the following code:

info.php
<?php
phpinfo();
?>

When you run this file, it will display a detailed page showing your PHP version and all enabled modules.

🎯 Exercise 1.1

Set up XAMPP, create a project folder in htdocs, and create a file called hello.php that outputs "Hello, PHP Mastery!" and your name. Run it by visiting localhost/your-folder/hello.php in your browser.

🎯 Exercise 1.2

Try removing the semicolon ; from the end of your echo statement and refresh the page. Read the error message—this will help you identify "Parse Errors" in the future.

Lecture 02 · Fundamentals

Variables & Data Types

Beginner ~45 min

Variables in PHP

Variables are "containers" for storing data. In PHP, all variables must start with a dollar sign $. This tells PHP that the word following the symbol is a variable name.

variables.php
$name = "John"; // String
$age = 25;       // Integer
$price = 19.99;    // Float

Variable Naming Rules

To keep your code clean and avoid errors, follow these rules when naming variables:

  • Must start with a letter or underscore: $name or $_user are valid; $1name is NOT.
  • Case-Sensitivity: $age and $AGE are two completely different variables.
  • Allowed Characters: Only letters, numbers, and underscores (A-z, 0-9, and _).

Dynamic Typing

PHP is a loosely typed language. This means you do not need to tell PHP what kind of data a variable holds (like int or string). PHP automatically converts the variable to the correct type based on the value you assign to it.

PHP Data Types

PHP supports several data types to handle different kinds of information. These are divided into three main categories:

1. Scalar Types (Single Values)

  • String: A sequence of characters wrapped in quotes.
    "Hello World"
  • Integer: A whole number without a decimal point.
    42
  • Float (Double): A number with a decimal point.
    3.14
  • Boolean: A value that is either true or false.

2. Compound Types (Multiple Values)

  • Array: A special variable that can hold multiple values in one single variable.
    $colors = ["Red", "Green", "Blue"];
  • Object: Instances of user-defined classes (covered in later lectures).

3. Special Types

  • NULL: A variable that has no value assigned to it.
    $x = NULL;

Inspecting Variables: var_dump()

Because PHP is dynamically typed, it can be hard to know exactly what type a variable is during a complex project. The var_dump() function is the most powerful debugging tool in PHP. It prints the type and the value of a variable.

debug.php
$age = 25;
$name = "Alice";

var_dump($age);  // Output: int(25)
var_dump($name); // Output: string(5) "Alice"
🎯 Exercise 2.1

Create a PHP script that defines the following variables:

  1. A string for your favorite movie.
  2. An integer for the release year.
  3. A float for the IMDB rating.
  4. A boolean for whether you have seen it more than once.
Use var_dump() on each variable to verify their data types in the browser.

Lecture 03 · Fundamentals

Operators & Expressions

Beginner ~40 min

Operators are the foundation of any programming language. They allow you to perform mathematical calculations, compare values, and manipulate strings to build dynamic logic in your PHP applications.

Arithmetic Operators

These are used to perform common mathematical operations. PHP supports all the standard operators you would expect.

  • + (Addition)
  • - (Subtraction)
  • * (Multiplication)
  • / (Division)
  • % (Modulo - returns the remainder of a division)
  • ** (Exponentiation - e.g., 2 to the power of 3)
math.php
echo (10 + 5); // 15
echo (10 % 3);  // 1 (Remainder)
echo (2 ** 3);  // 8

Assignment Operators

Assignment operators are used to assign values to variables. PHP provides "shorthand" operators to perform an operation and assign the result in one step.

assign.php
$x = 10; // Standard assignment
$x += 5;  // Same as $x = $x + 5 (Result: 15)
$x -= 2;  // Same as $x = $x - 2 (Result: 13)
$x *= 2;  // Same as $x = $x * 2 (Result: 26)

Comparison Operators

These operators compare two values and return a Boolean (either true or false). This is the basis for all "if" statements and loops.

  • == (Equal): Returns true if values are equal.
  • === (Identical): Returns true if values are equal and of the same type.
  • != (Not equal): Returns true if values are not equal.
  • <, >, <=, >= (Less than, Greater than, etc.)
compare.php
$a = "10";
$b = 10;

var_dump($a == $b); // true (Values are the same)
var_dump($a === $b); // false (One is a string, one is an int)

Logical Operators

Logical operators combine multiple comparison conditions to create more complex logic.

  • && (And): True if both conditions are true.
  • || (Or): True if at least one condition is true.
  • ! (Not): Reverses the boolean state (True becomes False).

String Operators & Expressions

PHP handles strings differently than numbers. One of the most important tools is Concatenation.

1. Concatenation (The Dot Operator)

In PHP, we use a dot . to join two or more strings together.

strings.php
$name = "John";
echo "Hello " . $name . "!"; // Hello John!

2. String Interpolation (Double Quotes)

Unlike some languages, PHP allows you to place variables directly inside double quotes. This is called interpolation and is often cleaner than using the dot operator.

strings.php
$name = "John";
echo "Hello $name!"; // Hello John! (Variable is parsed)

$age = 25;
echo "I am $age years old."; // I am 25 years old.

Warning: If you use single quotes (' '), PHP will treat the variable as literal text and will not parse it.

🎯 Exercise 3.1

Create a script that defines two variables: $price = 100 and $tax = 0.15. Calculate the total price (Price + (Price * Tax)) and print it using String Interpolation in a sentence like: "The total price is $115".

Lecture 04 · Fundamentals

Control Flow

Beginner ~45 min

Introduction to Control Flow

Control flow determines how a program makes decisions and repeats tasks. Instead of running every line sequentially, programs can choose different paths depending on conditions.

Control flow is one of the most important programming concepts because it allows applications to become interactive and intelligent.

Why Control Flow Matters

Control flow is used in almost every real-world application.

Examples include:

  • User login systems
  • Age verification
  • Game logic
  • Form validation
  • Repeating tasks with loops

If Statements

An if statement executes code only if a condition is true.

if ($age >= 18) {
    echo "Adult";
} else {
    echo "Minor";
}

In this example:

  • If $age is 18 or greater, the program prints Adult
  • Otherwise, it prints Minor

Understanding Comparison Operators

Comparison operators compare values inside conditions.

Operator Description
== Equal to
!= Not equal to
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to

Simple If Statement

An if statement can also be used without else.

$score = 90;

if ($score >= 50) {
    echo "Passed";
}

The message appears only if the condition is true.

If...Else Statements

if...else statements provide two possible execution paths.

$loggedIn = true;

if ($loggedIn) {
    echo "Welcome back";
} else {
    echo "Please log in";
}

Elseif Statements

elseif allows multiple conditions to be checked.

$grade = 85;

if ($grade >= 90) {
    echo "A";
} elseif ($grade >= 80) {
    echo "B";
} else {
    echo "C";
}

Logical Operators

Logical operators combine multiple conditions.

Operator Description
&& AND
|| OR
! NOT

Using AND Operator

$age = 20;
$hasID = true;

if ($age >= 18 && $hasID) {
    echo "Access granted";
}

Both conditions must be true.

Using OR Operator

$isAdmin = false;
$isEditor = true;

if ($isAdmin || $isEditor) {
    echo "Permission granted";
}

At least one condition must be true.

Switch Statements

The switch statement is useful when comparing one variable against multiple values.

$day = "Monday";

switch ($day) {

    case "Monday":
        echo "Start of the week";
        break;

    case "Friday":
        echo "Weekend is near";
        break;

    default:
        echo "Regular day";
}

Why break is Important

The break statement stops execution after a matching case is found.

Without break, PHP continues executing the next cases.

Introduction to Loops

Loops repeat blocks of code multiple times.

Loops are useful when working with lists, arrays, and repetitive tasks.

While Loops

A while loop repeats while a condition remains true.

$count = 1;

while ($count <= 5) {

    echo $count;

    $count
    

For Loops

for loops are commonly used when the number of repetitions is known.

for ($i = 1; $i <= 5; $i++) {

    echo $i;
}

Foreach Loops

foreach loops are designed for arrays.

$colors = array(
    "Red",
    "Blue",
    "Green"
);

foreach ($colors as $color) {

    echo $color;
}

Break and Continue

PHP provides loop control statements.

Statement Description
break Stops the loop completely
continue Skips the current iteration

Using break

for ($i = 1; $i <= 10; $i++) {

    if ($i == 5) {
        break;
    }

    echo $i;
}

Using continue

for ($i = 1; $i <= 5; $i++) {

    if ($i == 3) {
        continue;
    }

    echo $i;
}

Ternary Operator

The ternary operator provides a short version of an if...else statement.

$age = 20;

echo ($age >= 18) ? "Adult" : "Minor";

Nested Conditions

Conditions can exist inside other conditions.

$loggedIn = true;
$isAdmin = true;

if ($loggedIn) {

    if ($isAdmin) {
        echo "Admin Panel";
    }
}

Common Beginner Mistakes

  • Using = instead of == in conditions
  • Creating infinite loops
  • Forgetting curly braces
  • Missing break in switch statements
  • Using incorrect logical operators

Best Practices

  • Keep conditions readable
  • Avoid deeply nested logic
  • Use meaningful variable names
  • Prefer foreach for arrays
  • Use switch statements for multiple fixed options

Practice Exercise

Create:

  • An age checker using if...else
  • A grade system using elseif
  • A loop printing numbers from 1 to 10
  • A foreach loop displaying array values
$numbers = array(1, 2, 3, 4);

foreach ($numbers as $number) {

    echo $number;
}

Summary

In this lecture, you learned:

  • How decision-making works in PHP
  • How to use if, else, and elseif statements
  • How loops repeat code
  • How switch statements operate
  • How logical operators combine conditions
Lecture 05 · Fundamentals

Loops

Beginner ~40 min

Loops allow you to execute a block of code repeatedly as long as a certain condition is met. This is essential for processing lists of data, generating HTML tables, or performing repetitive calculations without writing the same code over and over.

The For Loop

The for loop is used when you know exactly how many times you want the loop to run. It combines initialization, condition, and increment in one line.

for_loop.php
// Count from 1 to 5
for ($i = 1; $i <= 5; $i++) {
    echo "The number is: $i 
"
; }

Breakdown:
$\rightarrow$ $i = 1: Starts the counter at 1.
$\rightarrow$ $i <= 5: The loop runs as long as this is true.
$\rightarrow$ $i++: Increases the counter by 1 after every loop.

The While Loop

The while loop is used when you don't know exactly how many times the loop should run, but you have a condition that must remain true for the loop to continue.

while_loop.php
$count = 1;

while ($count <= 3) {
    echo "Iteration number: $count 
"
; $count++; // Crucial: update the variable to avoid an infinite loop! }

The Do-While Loop

The do-while loop is a variant of the while loop. The key difference is that it executes the block of code once before checking the condition. This guarantees the code runs at least one time.

do_while.php
$i = 10;

do {
    echo "This will print even if the condition is false!";
    $i++;
} while ($i < 5); // Condition is false, but loop ran once

The Foreach Loop

The foreach loop is the most powerful tool for iterating through arrays. It doesn't require a counter; it simply goes through every element in the array from start to finish.

1. Iterating through Indexed Arrays

foreach_indexed.php
$colors = ["red", "green", "blue"];

foreach ($colors as $color) {
    echo "Color: $color 
"
; }

2. Iterating through Associative Arrays (Key $\rightarrow$ Value)

In many cases, you need both the key (the label) and the value. PHP allows you to capture both in the foreach syntax.

foreach_assoc.php
$ages = [
    "Peter" => 35, 
    "Ben" => 37, 
    "Joe" => 43
];

foreach ($ages as $name => $age) {
    echo "$name is $age years old 
"
; }

Loop Control: Break & Continue

Sometimes you need to exit a loop early or skip a specific iteration.

  • break: Stops the loop entirely and jumps to the next section of code.
  • continue: Skips the rest of the current iteration and jumps straight to the next loop cycle.
control.php
for ($i = 0; $i < 10; $i++) {
    if ($i == 3) continue; // Skip number 3
    if ($i == 7) break;      // Stop loop at 7
    echo $i;
}
🎯 Exercise 5.1

Create an associative array called $products where the keys are product names (e.g., "Laptop", "Phone", "Mouse") and the values are their prices. Use a foreach loop to print a list that says: "The [Product] costs $[Price]".

Lecture 06 · Core Concepts

Functions

Intermediate ~50 min

Introduction to Functions

Functions are reusable blocks of code designed to perform specific tasks. Instead of writing the same logic multiple times, developers can place the logic inside a function and call it whenever needed.

Functions help make code:

  • Cleaner
  • Reusable
  • Easier to debug
  • More organized
  • Easier to maintain

Functions are heavily used in real-world PHP applications, frameworks, APIs, and backend systems.

Creating a Function

Functions in PHP are created using the function keyword.

function sum($a, $b) {

    return $a + $b;
}

In this example:

  • sum is the function name.
  • $a and $b are parameters.
  • return sends a value back to the caller.

Calling a Function

After creating a function, you can execute it by calling its name.

echo sum(5, 3);

The output will be:

8

Function Parameters

Parameters allow functions to accept input values.

function greet($name) {

    echo "Hello " . $name;
}
greet("John");

Functions become more flexible when they accept parameters.

Default Parameter Values

PHP allows default values for parameters.

function welcome($name = "Guest") {

    echo "Welcome " . $name;
}

If no argument is passed, PHP uses the default value.

welcome();

welcome("Alice");

Returning Values

Functions can return values using the return keyword.

function square($num) {

    return $num * $num;
}

$result = square(4);

echo $result;

The returned value can be stored in variables or used directly.

Function Scope

Variables declared inside a function are local to that function.

function test() {

    $message = "Hello";

    echo $message;
}

The variable $message cannot be accessed outside the function.

Global Variables

Global variables can be accessed inside functions using the global keyword.

$count = 10;

function showCount() {

    global $count;

    echo $count;
}

Although possible, excessive use of global variables is discouraged because it makes code harder to maintain.

Type Declarations

Modern PHP supports type declarations for parameters and return values.

function multiply(int $a, int $b): int {

    return $a * $b;
}

This improves code reliability and reduces unexpected bugs.

Anonymous Functions

PHP supports anonymous functions, also known as closures.

$greet = function($name) {

    echo "Hello " . $name;
};

Anonymous functions are useful when passing functions as arguments or storing them inside variables.

Arrow Functions

PHP also provides shorter arrow function syntax.

$square = fn($x) => $x * $x;

Arrow functions are cleaner for simple one-line expressions.

Variable-Length Arguments

PHP allows functions to accept an unknown number of arguments using the spread operator.

function total(...$numbers) {

    $sum = 0;

    foreach($numbers as $num) {

        $sum += $num;
    }

    return $sum;
}

This feature is useful when the number of inputs is unknown.

Recursive Functions

A recursive function is a function that calls itself.

function factorial($n) {

    if($n <= 1) {

        return 1;
    }

    return $n * factorial($n - 1);
}

Recursion is commonly used in mathematical calculations, tree structures, and algorithms.

Built-in PHP Functions

PHP includes thousands of built-in functions for common tasks.

strlen("Hello");

strtoupper("php");

date("Y-m-d");

Learning built-in functions can greatly speed up development.

Benefits of Functions

  • Reduce repeated code.
  • Improve readability.
  • Make debugging easier.
  • Encourage modular programming.
  • Simplify large applications.

Common Beginner Mistakes

  • Forgetting to return values.
  • Using undefined variables inside functions.
  • Confusing local and global scope.
  • Passing incorrect argument types.
  • Creating overly large functions.

Practice

Practice

Create a function called average() that accepts three numbers and returns their average.

Then create an arrow function that multiplies two values.

Summary

Functions are one of the most important features in PHP. They allow developers to organize logic into reusable and maintainable blocks of code.

Mastering functions is essential for building dynamic websites, backend systems, APIs, and professional PHP applications.

Lecture 07 · Core Concepts

Arrays & Superglobals

Intermediate ~55 min

Introduction to Arrays

Arrays are one of the most important data structures in PHP. They allow developers to store multiple values inside a single variable.

Instead of creating many separate variables, arrays help organize related data together.

PHP arrays are flexible and can store:

  • Strings
  • Numbers
  • Booleans
  • Objects
  • Even other arrays

Indexed Arrays

Indexed arrays store values using numeric indexes starting from 0.

$colors = ["Red", "Blue", "Green"];

echo $colors[0];

The output will be:

Red

Adding Elements to Arrays

New elements can be added using square brackets.

$colors[] = "Yellow";

PHP automatically places the value at the next available index.

Associative Arrays

Associative arrays use named keys instead of numeric indexes.

$person = [

    "name" => "Jane",

    "role" => "Manager"
];

Associative arrays are useful when storing structured data.

Accessing Associative Array Values

echo $person["name"];

The output will be:

Jane

Updating Array Values

Existing array values can be modified easily.

$person["role"] = "Developer";

This replaces the old value with a new one.

Multidimensional Arrays

PHP supports arrays inside arrays, known as multidimensional arrays.

$students = [

    [
        "name" => "John",
        "grade" => 90
    ],

    [
        "name" => "Alice",
        "grade" => 85
    ]
];

This structure is commonly used when handling database-like data.

Looping Through Arrays

The foreach loop is commonly used to iterate through arrays.

foreach($colors as $color) {

    echo $color;
}

This loop processes each element one at a time.

Looping Through Associative Arrays

You can access both keys and values during iteration.

foreach($person as $key => $value) {

    echo $key . ": " . $value;
}

Useful Array Functions

PHP provides many built-in array functions.

count($colors);

sort($colors);

array_push($colors, "Black");

These functions simplify common array operations.

The count() Function

The count() function returns the total number of elements.

echo count($colors);

Sorting Arrays

Arrays can be sorted alphabetically or numerically.

sort($colors);

rsort($colors);

sort() sorts in ascending order while rsort() sorts in descending order.

Introduction to Superglobals

Superglobals are predefined PHP variables available in every scope.

They are commonly used to handle:

  • Form data
  • User sessions
  • Cookies
  • Server information
  • File uploads

The $_GET Superglobal

$_GET collects data sent through URL parameters.

$name = $_GET["name"];

echo $name;

Example URL:

example.php?name=John

The $_POST Superglobal

$_POST collects form data sent using the POST method.

$email = $_POST["email"];

POST requests are more secure for sensitive data than GET requests.

The $_SERVER Superglobal

$_SERVER contains information about the server and request environment.

echo $_SERVER["PHP_SELF"];

echo $_SERVER["SERVER_NAME"];

The $_SESSION Superglobal

Sessions allow data to persist across multiple pages.

session_start();

$_SESSION["user"] = "Admin";

Sessions are commonly used for authentication systems.

The $_COOKIE Superglobal

Cookies store small pieces of data inside the user’s browser.

setcookie("theme", "dark", time() + 3600);

This cookie remains available for one hour.

The $_FILES Superglobal

$_FILES handles uploaded files.

$fileName = $_FILES["image"]["name"];

This is commonly used in upload forms and media systems.

Security Best Practices

Never trust user input directly. Always validate and sanitize data received through superglobals.

$name = htmlspecialchars($_POST["name"]);

This helps prevent XSS attacks.

Benefits of Arrays & Superglobals

  • Store and organize data efficiently.
  • Handle dynamic web content.
  • Process user input.
  • Support sessions and authentication.
  • Enable form handling and uploads.

Common Beginner Mistakes

  • Using undefined array indexes.
  • Forgetting to sanitize user input.
  • Mixing associative and indexed arrays incorrectly.
  • Using GET for sensitive information.
  • Forgetting to call session_start().

Practice

Practice

Create an associative array called $student with keys for name, age, and grade.

Then write a foreach loop to display all keys and values.

Finally, create a simple form that sends data using the POST method and access the values using $_POST.

Summary

Arrays and superglobals are essential features in PHP development. Arrays help organize and manage data efficiently, while superglobals allow applications to interact with users, forms, sessions, servers, and uploaded files.

Understanding these concepts is critical for building dynamic and interactive PHP applications.

Lecture 08 · Core Concepts

Strings & Forms

Intermediate ~45 min

Introduction to Strings in PHP

Strings are sequences of characters used to store and manipulate text. In PHP, strings are extremely important because web applications frequently work with usernames, passwords, messages, emails, and form input.

PHP provides many built-in functions for working with strings efficiently.

  • Displaying text on web pages
  • Processing user input
  • Validating form data
  • Generating dynamic content

Creating Strings

Strings can be created using single quotes or double quotes.

$name = "PHP";

$message = 'Hello World';

Single Quotes vs Double Quotes

Double quotes allow variable interpolation, while single quotes treat text literally.

$language = "PHP";

echo "Learning $language";

echo 'Learning $language';

String Concatenation

PHP uses the dot (.) operator to combine strings.

$first = "Hello";

$second = "World";

echo $first . " " . $second;

Useful String Functions

Function Purpose
strlen() Returns string length
strtoupper() Converts text to uppercase
strtolower() Converts text to lowercase
trim() Removes extra spaces
strpos() Finds text position

Example: String Functions

$text = "  PHP Programming  ";

echo trim($text);

echo strtoupper($text);

echo strlen($text);

Searching Inside Strings

The strpos() function searches for text inside a string.

$sentence = "I love PHP";

echo strpos($sentence, "PHP");

Replacing Text

The str_replace() function replaces parts of a string.

echo str_replace(
    "PHP",
    "Laravel",
    "PHP is powerful"
);

Introduction to Forms

Forms allow users to send data to the server. PHP commonly handles form submissions using $_GET and $_POST.

Forms are used in:

  • Login systems
  • Registration pages
  • Search boxes
  • Contact forms
  • Feedback systems

Basic HTML Form

<form method="post">

    <input type="text" name="username">

    <button type="submit">Send</button>

</form>

Handling Form Data with $_POST

The $_POST superglobal stores data submitted using the POST method.

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

    $username = $_POST["username"];

    echo "Welcome " . $username;
}

Handling Form Data with $_GET

The $_GET superglobal retrieves data from the URL query string.

<form method="get">

    <input type="text" name="search">

</form>
$search = $_GET["search"];

echo $search;

GET vs POST

GET POST
Data visible in URL Data hidden from URL
Less secure More secure
Good for searches Good for passwords/forms

Checking Form Fields

PHP provides functions for validating form input.

if (empty($_POST["email"])) {

    echo "Email is required";
}

Sanitizing User Input

User input should always be cleaned before displaying or storing it.

$name = htmlspecialchars(
    $_POST["name"]
);

This prevents malicious HTML or JavaScript injection.

Working with Multiple Form Fields

<form method="post">

    <input type="text" name="name">

    <input type="email" name="email">

    <button>Submit</button>

</form>
$name = $_POST["name"];

$email = $_POST["email"];

echo $name;

echo $email;

Form Validation Example

if (strlen($_POST["password"]) < 6) {

    echo "Password too short";
}

Best Practices for Forms

  • Always validate user input
  • Use POST for sensitive data
  • Sanitize form values before output
  • Check if fields are empty
  • Provide meaningful error messages

Common Mistakes

  • Trusting user input directly
  • Using GET for passwords
  • Forgetting validation checks
  • Ignoring security vulnerabilities
  • Accessing undefined form fields

Mini Practice

Try creating the following:

  • A login form using POST
  • A search form using GET
  • A string manipulation example
  • A form validation system
  • A secure form using htmlspecialchars()
Lecture 09 · Core Concepts

Sessions & Cookies

Intermediate ~45 min

Introduction to Sessions & Cookies

Modern web applications need a way to remember users between requests. Since HTTP is stateless, PHP uses sessions and cookies to store user-related data.

Sessions and cookies are commonly used for:

  • User authentication
  • Login systems
  • Shopping carts
  • User preferences
  • Theme settings

Understanding Stateless HTTP

Every HTTP request is independent. Without sessions or cookies, the server forgets the user after each request.

Sessions and cookies solve this problem by storing user information temporarily.

Sessions

Sessions store data on the server. Each user receives a unique session ID that connects requests together.

<?php

session_start();

$_SESSION['user'] = 'Ahmed';

$_SESSION['role'] = 'admin';

echo $_SESSION['user']; // Ahmed

// Destroy
session_unset();

session_destroy();

?>

How Sessions Work

  1. User visits the website
  2. PHP creates a unique session ID
  3. The ID is stored in the browser
  4. Session data is stored on the server
  5. Future requests use the same session ID

Starting a Session

The session_start() function must be called before accessing session data.

<?php

session_start();

?>

This function should appear before any HTML output.

Storing Session Data

Session variables are stored using the $_SESSION superglobal.

$_SESSION['username'] = 'admin';

$_SESSION['email'] = 'admin@example.com';

Reading Session Values

echo $_SESSION['username'];

Checking if a Session Exists

if (isset($_SESSION['username'])) {

    echo "User logged in";
}

Destroying Sessions

Sessions should be destroyed during logout.

session_unset();

session_destroy();

Session Timeout Concept

Sessions usually expire after inactivity for security reasons.

$_SESSION['last_activity'] = time();

Applications can compare timestamps to automatically log out inactive users.

Cookies

Cookies store small pieces of data directly in the user's browser.

Unlike sessions, cookies are stored on the client side.

// Set cookie (expires in 1 hour)

setcookie('theme', 'dark', time() + 3600, '/');

// Read cookie

echo $_COOKIE['theme'] ?? 'light';

// Delete

setcookie('theme', '', time() - 3600, '/');

Cookie Parameters

Parameter Purpose
Name Cookie identifier
Value Stored data
Expiration Expiry time
Path Accessible directory

Setting Cookies

Cookies are created using the setcookie() function.

setcookie(
    'language',
    'English',
    time() + 86400,
    '/'
);

Reading Cookies

echo $_COOKIE['language'];

Deleting Cookies

Cookies are deleted by setting an expiration time in the past.

setcookie(
    'language',
    '',
    time() - 3600,
    '/'
);

Sessions vs Cookies

Sessions Cookies
Stored on server Stored in browser
More secure Less secure
Temporary Can persist longer
Requires session ID Sent automatically with requests

Login Example

Sessions are commonly used for authentication systems.

session_start();

if ($_POST['user'] === 'admin' &&
    $_POST['pass'] === 'secret') {

    $_SESSION['logged_in'] = true;

    header('Location: dashboard.php');

    exit;
}

Protecting Pages with Sessions

session_start();

if (!isset($_SESSION['logged_in'])) {

    header('Location: login.php');

    exit;
}

Logout System

session_start();

session_unset();

session_destroy();

header('Location: login.php');

Remember Me Feature

Cookies are often used for "Remember Me" functionality.

setcookie(
    'remember_user',
    'admin',
    time() + (86400 * 30),
    '/'
);

Security Best Practices

  • Never store passwords in cookies
  • Use HTTPS for secure sessions
  • Destroy sessions during logout
  • Validate session data properly
  • Regenerate session IDs after login

Regenerating Session IDs

Regenerating session IDs helps prevent session hijacking attacks.

session_regenerate_id(true);

Common Mistakes

  • Forgetting to call session_start()
  • Sending output before sessions start
  • Storing sensitive data in cookies
  • Ignoring session security
  • Not validating login sessions

Real-World Applications

  • User dashboards
  • E-commerce carts
  • Admin panels
  • Theme personalization
  • Authentication systems
Practice

Build a login/logout system with session-based authentication.

  • Create a login form
  • Store user information in sessions
  • Protect private pages
  • Create a logout button
  • Store theme preferences using cookies
Lecture 10 · OOP & Advanced

Object-Oriented PHP

Advanced ~65 min

Object-Oriented Programming (OOP) is a programming paradigm that allows developers to organize code into reusable objects and classes. Instead of writing everything as separate functions and variables, OOP helps group related data and behaviors together. This approach makes applications easier to manage, maintain, and expand.

PHP provides powerful support for Object-Oriented Programming. Most modern PHP frameworks such as Laravel, Symfony, and CodeIgniter are heavily based on OOP concepts. Learning OOP is essential for building professional web applications.

What is a Class?

A class is a blueprint or template used to create objects. It defines the properties (variables) and methods (functions) that an object can have.

class User {
    public $name;
}

In the above example, User is a class and $name is a property of that class.

What is an Object?

An object is an instance of a class. Once a class is created, multiple objects can be generated from it.

$user1 = new User();
$user1->name = "John";

echo $user1->name;

Here, $user1 is an object created from the User class.

Properties and Methods

Properties store information about an object, while methods define actions that the object can perform.

class User {

    public $name;

    public function greet() {
        echo "Hello " . $this->name;
    }
}

The method greet() uses the object's name property to display a personalized greeting.

The $this Keyword

The $this keyword refers to the current object. It is used inside a class to access properties and methods belonging to that object.

$this->name

Whenever PHP encounters $this, it understands that you are referring to the object that is currently executing the code.

Constructors

A constructor is a special method that runs automatically whenever an object is created. Constructors are commonly used to initialize object properties.

class User {
    public $name;

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

The constructor receives a name value and stores it inside the object's property automatically during creation.

$user = new User("Alice");

Access Modifiers

Access modifiers determine where properties and methods can be accessed. PHP provides three visibility levels:

  • public – Accessible from anywhere.
  • protected – Accessible within the class and inherited classes.
  • private – Accessible only within the same class.
class Account {
    private $balance = 1000;
}

Inheritance

Inheritance allows one class to acquire properties and methods from another class. This promotes code reusability and reduces duplication.

class Person {
    public $name;
}

class Student extends Person {
    public $course;
}

The Student class inherits all accessible members of the Person class.

Method Overriding

A child class can redefine a method inherited from a parent class. This process is known as method overriding.

class Animal {
    public function sound() {
        echo "Animal Sound";
    }
}

class Dog extends Animal {
    public function sound() {
        echo "Bark";
    }
}

Encapsulation

Encapsulation is the practice of hiding sensitive data and providing controlled access through methods. This improves security and prevents accidental modification.

class BankAccount {

    private $balance = 5000;

    public function getBalance() {
        return $this->balance;
    }
}

Polymorphism

Polymorphism allows different classes to use the same method name while providing different implementations. This makes code more flexible and easier to extend.

For example, multiple payment classes such as CreditCard, PayPal, and UPI may all contain a pay() method, but each class processes payments differently.

Static Properties and Methods

Static members belong to the class itself rather than individual objects. They can be accessed without creating an object.

class MathUtil {

    public static function square($num) {
        return $num * $num;
    }
}

echo MathUtil::square(5);

Benefits of OOP

  • Improves code organization.
  • Encourages code reuse.
  • Makes large applications easier to maintain.
  • Enhances security through encapsulation.
  • Simplifies debugging and testing.
  • Supports scalable application development.

Real-World Example

Consider an online learning platform. You might create classes such as:

  • Student
  • Instructor
  • Course
  • Lesson
  • Quiz

Each class stores its own data and methods. This structure keeps the application organized and makes future updates much easier.

class Course {

    public $title;

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

$course = new Course("PHP Mastery");

echo $course->title;

Summary

Object-Oriented Programming is one of the most important concepts in modern PHP development. By using classes, objects, inheritance, encapsulation, polymorphism, constructors, and static methods, developers can create powerful, scalable, and maintainable web applications.

class User {
    public $name;

    function __construct($name) {
        $this->name = $name;
    }
}
Lecture 11 · OOP & Advanced

Namespaces & Composer

Intermediate ~45 min

As PHP applications grow larger, managing files, classes, and external libraries becomes increasingly challenging. Namespaces and Composer solve these problems by organizing code efficiently and automatically loading required classes.

Modern PHP development heavily relies on Namespaces and Composer. Popular frameworks such as Laravel, Symfony, and CodeIgniter use these concepts extensively. Learning them is an important step toward professional PHP development.

What are Namespaces?

A namespace is a way of organizing related classes, interfaces, traits, and functions into logical groups. Namespaces help prevent naming conflicts when different classes share the same name.

For example, two developers might create a class called User. Without namespaces, PHP would not know which User class to use. Namespaces solve this issue by placing classes inside separate containers.

// App\Models\User
namespace App\Models;

class User {}

// App\Admin\User
namespace App\Admin;

class User {}

Even though both classes are named User, PHP can distinguish them because they belong to different namespaces.

Namespaces

The namespace keyword is placed at the top of a PHP file and defines the namespace to which the class belongs.

// src/Models/User.php
<?php
namespace App\Models;

class User {
    public function __construct(public string $name) {}
}

// index.php
require 'src/Models/User.php';

use App\Models\User;

$u = new User('Ahmed');

In this example, the User class belongs to the App\Models namespace. The use keyword imports the class so it can be referenced easily within the file.

Understanding the use Keyword

The use statement allows you to create an alias or shortcut to a fully qualified class name. This improves readability and reduces the need to type long namespace paths repeatedly.

use App\Models\User;

$user = new User("John");

Without the use statement, you would need to write the complete namespace path whenever creating an object.

$user = new App\Models\User("John");

Benefits of Namespaces

  • Avoid class naming conflicts.
  • Improve project organization.
  • Make large applications easier to manage.
  • Support third-party packages safely.
  • Provide cleaner and more maintainable code.

Project Structure Example

A typical PHP application using namespaces may have the following folder structure:

project/
│
├── src/
│   ├── Models/
│   │   └── User.php
│   │
│   ├── Controllers/
│   │   └── UserController.php
│   │
│   └── Services/
│       └── EmailService.php
│
├── vendor/
├── composer.json
└── index.php

This structure keeps different parts of the application separated and easier to locate during development.

Introduction to Composer

Composer is the most popular dependency manager for PHP. It allows developers to install, update, and manage external packages and libraries with simple commands.

Instead of downloading libraries manually, Composer automatically handles package installation, version management, and autoloading.

Why Use Composer?

  • Installs third-party libraries automatically.
  • Manages package dependencies.
  • Provides automatic class loading.
  • Keeps projects organized and maintainable.
  • Supports version control for packages.

Composer Setup

Composer only needs to be installed once on your system. After installation, it can be used in any PHP project.

# Install Composer (one-time)
curl -sS https://getcomposer.org/installer | php

# Create composer.json
composer init

# Install a package
composer require monolog/monolog
composer require --dev phpunit/phpunit

The composer init command creates a composer.json file that stores project information and package dependencies.

Understanding composer.json

The composer.json file is the heart of every Composer project. It contains package requirements, autoloading rules, project metadata, and configuration settings.

{
    "name": "mycompany/myproject",
    "description": "Learning Composer",
    "require": {
        "monolog/monolog": "^3.0"
    }
}

Whenever packages are installed, Composer records them in this file so that the project can be recreated easily on another machine.

Installing Packages

Composer packages are stored on Packagist, the official PHP package repository. Thousands of libraries are available for logging, authentication, APIs, testing, image processing, payments, and more.

composer require monolog/monolog

This command downloads Monolog and all of its required dependencies into the vendor directory.

The vendor Directory

After installing packages, Composer creates a vendor folder. This folder contains all downloaded libraries and the autoloader used by your application.

project/
│
├── vendor/
│   ├── autoload.php
│   └── ...
│
├── composer.json
└── index.php

The vendor folder is automatically managed by Composer and generally should not be edited manually.

Autoloading (PSR-4)

One of Composer's most powerful features is automatic class loading. Instead of manually including every file using require or include statements, Composer loads classes automatically when needed.

// composer.json
{
  "autoload": {
    "psr-4": {
      "App\\": "src/"
    }
  }
}

// Then:
composer dump-autoload

// index.php
require 'vendor/autoload.php';

use App\Models\User;

The PSR-4 standard maps namespaces to directories. In this example, classes beginning with App\ will be searched inside the src directory automatically.

How PSR-4 Works

Consider the namespace below:

namespace App\Models;

With the PSR-4 configuration:

"App\\": "src/"

Composer automatically expects the file to exist at:

src/Models/User.php

This convention makes large projects much easier to navigate and maintain.

Generating the Autoloader

Whenever you add new classes or modify autoload configurations, run the following command:

composer dump-autoload

Composer will regenerate the autoload files so that newly created classes can be discovered automatically.

Real-World Example with Monolog

Monolog is one of the most widely used PHP logging libraries. It allows applications to store logs in files, databases, cloud services, and more.

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$log = new Logger('app');

$log->pushHandler(
    new StreamHandler('app.log')
);

$log->info('Application Started');

This example writes a log message to a file named app.log.

Best Practices

  • Always use namespaces in large projects.
  • Follow PSR-4 standards consistently.
  • Use Composer to manage dependencies.
  • Do not manually edit vendor files.
  • Keep composer.json under version control.
  • Update dependencies regularly.

Summary

Namespaces help organize classes and prevent naming conflicts, while Composer simplifies dependency management and class autoloading. Together they form the foundation of modern PHP development and are used in nearly every professional PHP application today.

Practice

Set up a Composer project, autoload your classes using PSR-4, create multiple namespaces, install Monolog, and write log messages to a file. Try creating a small project with Models, Controllers, and Services directories to understand how namespaces and autoloading work together.

Lecture 12 · OOP & Advanced

Exceptions & Error Handling

Intermediate ~45 min

Errors are a natural part of software development. Files may be missing, database connections can fail, users might enter invalid data, and external APIs may become unavailable. A professional PHP application should handle these situations gracefully instead of crashing unexpectedly.

PHP provides a powerful exception handling system that allows developers to detect errors, respond appropriately, and maintain application stability. Exception handling makes applications easier to debug, maintain, and secure.

What is an Exception?

An exception is an object that represents an error or unexpected event occurring during program execution. When an exception is thrown, PHP stops the normal flow of the program and searches for code that can handle the exception.

Without exception handling, many runtime errors would terminate the script immediately. Using exceptions allows developers to recover from errors and provide meaningful feedback to users.

throw new Exception("Something went wrong");

The throw keyword is used to create and trigger an exception.

Why Use Exception Handling?

  • Prevents application crashes.
  • Provides meaningful error messages.
  • Separates error-handling logic from business logic.
  • Improves debugging and maintenance.
  • Allows centralized error management.
  • Creates more reliable applications.

Try-Catch

The most common way to handle exceptions is through the try-catch block. Code that may generate an exception is placed inside the try block. If an exception occurs, PHP transfers execution to the appropriate catch block.

try {
    $result = 10 / 0;
} catch (DivisionByZeroError $e) {
    echo "Math error: " . $e->getMessage();
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
} finally {
    echo "Cleanup.";
}

In this example, dividing by zero triggers a DivisionByZeroError. The matching catch block handles the error and displays a message.

Understanding the Try Block

The try block contains code that may potentially fail. PHP continuously monitors the code inside this block for exceptions.

try {
    connectToDatabase();
}

If no exception occurs, the catch blocks are skipped and execution continues normally.

Understanding the Catch Block

The catch block receives the exception object and allows developers to handle the error appropriately.

catch (Exception $e) {
    echo $e->getMessage();
}

The variable $e contains information about the exception, including its message, file name, line number, and stack trace.

Exception Methods

Exception objects provide several useful methods for retrieving error details.

try {
    throw new Exception("Database failed");
} catch (Exception $e) {

    echo $e->getMessage();
    echo $e->getCode();
    echo $e->getFile();
    echo $e->getLine();
}
  • getMessage() – Returns the error message.
  • getCode() – Returns the exception code.
  • getFile() – Returns the file where the exception occurred.
  • getLine() – Returns the line number.
  • getTrace() – Returns the stack trace.

Multiple Catch Blocks

PHP allows multiple catch blocks so different types of exceptions can be handled differently.

try {

    // Risky operation

} catch (PDOException $e) {

    echo "Database Error";

} catch (Exception $e) {

    echo "General Error";
}

This approach provides more precise control over application behavior.

The Finally Block

The finally block always executes regardless of whether an exception occurs. It is commonly used for cleanup operations such as closing files, releasing resources, or terminating database connections.

try {

    // Code

} catch (Exception $e) {

    // Handle Error

} finally {

    echo "Cleanup completed";
}

The finally block ensures important cleanup code always runs.

Throwing Custom Exceptions

Sometimes built-in exceptions are not descriptive enough. PHP allows developers to create custom exception classes tailored to application needs.

Custom Exception

class InvalidUserException extends Exception {}

function getUser(int $id): User {
    $u = User::find($id);

    if (!$u)
        throw new InvalidUserException("User $id not found");

    return $u;
}

try {
    $user = getUser(99);
} catch (InvalidUserException $e) {
    http_response_code(404);
    echo $e->getMessage();
}

Creating custom exceptions makes error messages more meaningful and helps identify the exact type of problem that occurred.

Creating Multiple Custom Exceptions

Large applications often define different exceptions for different scenarios.

class UserNotFoundException extends Exception {}

class ValidationException extends Exception {}

class DatabaseException extends Exception {}

Each exception represents a specific problem, making debugging easier.

Exception Hierarchies

Custom exceptions can inherit from other custom exceptions. This allows related errors to be grouped together.

class ApplicationException extends Exception {}

class DatabaseException extends ApplicationException {}

class ValidationException extends ApplicationException {}

Catching the parent exception allows multiple related exceptions to be handled together.

Handling Database Errors

Database operations frequently generate exceptions. PDO can be configured to throw exceptions automatically whenever a query fails.

$pdo->setAttribute(
    PDO::ATTR_ERRMODE,
    PDO::ERRMODE_EXCEPTION
);

This makes database debugging significantly easier.

Logging Exceptions

Instead of displaying technical errors to users, production applications typically log errors to files for later analysis.

try {

    // Operation

} catch (Exception $e) {

    error_log($e->getMessage());
}

Logging preserves useful debugging information while protecting sensitive application details.

Global Error Handling

PHP provides functions that allow developers to handle errors globally throughout an application.

set_error_handler

set_error_handler(function($errno, $errstr, $errfile, $errline) {

    error_log("[$errno] $errstr in $errfile:$errline");

    return true;
});

This custom error handler intercepts PHP warnings and notices, allowing them to be logged or processed centrally.

set_exception_handler

Uncaught exceptions can be handled globally using the set_exception_handler() function.

set_exception_handler(function($e) {

    error_log($e->getMessage());

    echo "An unexpected error occurred.";
});

This prevents users from seeing raw exception details while ensuring developers still receive diagnostic information.

Error Handling Best Practices

  • Use exceptions for exceptional situations.
  • Never expose sensitive error details to users.
  • Log errors for debugging purposes.
  • Create meaningful custom exception classes.
  • Handle database and API failures gracefully.
  • Use finally blocks for cleanup operations.
  • Implement global exception handlers in production.

Real-World Example

Imagine an online shopping application. When a customer places an order, several things could go wrong:

  • The product may not exist.
  • The database connection may fail.
  • Payment processing may be unavailable.
  • Required customer data may be missing.

By throwing and handling custom exceptions, each problem can be managed appropriately without crashing the entire application.

Summary

Exception handling is a critical part of modern PHP development. Using try-catch blocks, custom exceptions, logging, and global handlers allows applications to recover from errors gracefully and provide a better user experience. Proper error handling leads to more secure, reliable, and maintainable software.

Practice

Build a UserRepository that throws different custom exceptions for user-not-found errors, validation failures, and database connection issues. Add logging and create a global exception handler to manage uncaught exceptions throughout the application.

Lecture 13 · OOP & Advanced

File I/O & Security

Advanced ~50 min

File handling and application security are two critical aspects of PHP development. Most real-world applications need to read files, write logs, process uploads, generate reports, or store temporary data. At the same time, developers must ensure that user input cannot be used to compromise the application.

In this lecture, you will learn how to work with files in PHP and understand common security threats such as XSS, file upload vulnerabilities, directory traversal attacks, and insecure data handling.

Introduction to File I/O

File I/O (Input/Output) refers to reading data from files and writing data to files. PHP provides a variety of built-in functions that make file manipulation simple and efficient.

Common use cases include:

  • Storing logs.
  • Reading configuration files.
  • Generating reports.
  • Uploading files.
  • Exporting data.
  • Importing CSV files.

Reading Files

PHP provides the file_get_contents() function to read an entire file into a string.

$content = file_get_contents("notes.txt");

echo $content;

This function is ideal for small and medium-sized files where the entire content needs to be loaded at once.

Reading Files Line by Line

For larger files, it is often better to read data one line at a time.

$file = fopen("data.txt", "r");

while (($line = fgets($file)) !== false) {
    echo $line;
}

fclose($file);

This approach consumes less memory and is more suitable for processing large files.

Writing Files

The file_put_contents() function can be used to create files or overwrite existing file contents.

file_put_contents(
    "log.txt",
    "Application Started"
);

If the file does not exist, PHP automatically creates it.

Appending Data to Files

Sometimes you want to add new content without deleting existing data. The FILE_APPEND flag makes this possible.

file_put_contents(
    "log.txt",
    "New Log Entry\n",
    FILE_APPEND
);

This is commonly used for application logging.

Using fopen()

The fopen() function provides greater control over file operations through various modes.

$file = fopen("sample.txt", "w");

fwrite($file, "Hello World");

fclose($file);

Common File Modes

Mode Description
r Read only.
w Write only and overwrite.
a Append data.
r+ Read and write.
w+ Read, write, and overwrite.

Checking File Existence

Before accessing a file, it is good practice to verify that it exists.

if (file_exists("config.php")) {
    echo "File Found";
}

This prevents warnings and unexpected runtime errors.

Working with Directories

PHP also provides functions for creating and managing directories.

mkdir("uploads");

if (is_dir("uploads")) {
    echo "Directory Exists";
}

File Uploads

File uploads are one of the most common features in web applications. PHP stores uploaded files temporarily and provides access through the $_FILES superglobal.

<form method="POST"
      enctype="multipart/form-data">

    <input type="file" name="photo">

    <button type="submit">
        Upload
    </button>

</form>

Processing Uploaded Files

move_uploaded_file(
    $_FILES['photo']['tmp_name'],
    "uploads/" . $_FILES['photo']['name']
);

This moves the uploaded file from the temporary location to the desired destination folder.

Security Fundamentals

Security should be considered from the beginning of every project. Even small vulnerabilities can lead to serious consequences such as data theft, account compromise, or complete server takeover.

Cross-Site Scripting (XSS)

XSS occurs when attackers inject malicious JavaScript into web pages. This script may steal cookies, session data, or manipulate content displayed to users.

Always sanitize your inputs using htmlspecialchars() to prevent XSS attacks.

$safeName = htmlspecialchars(
    $_POST['name']
);

echo $safeName;

This converts special characters into HTML entities, preventing scripts from being executed in the browser.

Example of an XSS Attack

<script>
alert('Hacked');
</script>

Without proper sanitization, code like this could be executed in a user's browser. Using htmlspecialchars() renders it harmless text.

SQL Injection Prevention

SQL Injection occurs when attackers manipulate database queries through user input. Prepared statements should always be used when working with databases.

$stmt = $pdo->prepare(
    "SELECT * FROM users WHERE email = ?"
);

$stmt->execute([$email]);

Prepared statements separate SQL code from user data, making injection attacks significantly more difficult.

File Upload Security

Never trust uploaded files blindly. Attackers may upload executable scripts disguised as images or documents.

$allowedTypes = [
    'image/jpeg',
    'image/png'
];

if (
    in_array(
        $_FILES['photo']['type'],
        $allowedTypes
    )
) {
    echo "Valid File";
}

Validate File Extensions

$extension = pathinfo(
    $_FILES['photo']['name'],
    PATHINFO_EXTENSION
);

$allowed = ['jpg', 'png'];

if (
    in_array($extension, $allowed)
) {
    echo "Allowed";
}

Always validate both MIME types and file extensions before storing uploads.

Directory Traversal Attacks

Directory traversal attacks occur when users manipulate file paths to access sensitive files outside the intended directory.

../../../../etc/passwd

Never allow users to directly control file paths without validation.

Password Security

Passwords should never be stored in plain text. PHP provides secure password hashing functions.

$hash = password_hash(
    $password,
    PASSWORD_DEFAULT
);

if (
    password_verify(
        $password,
        $hash
    )
) {
    echo "Valid Password";
}

Session Security

Sessions help identify authenticated users. Proper session management is essential for application security.

session_start();

session_regenerate_id(true);

Regenerating session IDs helps protect against session fixation attacks.

Logging Security Events

Security-related actions should be logged for auditing and troubleshooting.

error_log(
    "Failed login attempt"
);

Best Practices

  • Always validate user input.
  • Sanitize output before displaying it.
  • Use prepared statements for database queries.
  • Store passwords using password_hash().
  • Restrict uploaded file types.
  • Never trust user-provided file paths.
  • Keep sensitive files outside public directories.
  • Use HTTPS in production environments.
  • Log security-related events.
  • Regularly update PHP and dependencies.

Summary

File I/O allows PHP applications to read, write, upload, and manage files efficiently. However, file operations must always be implemented securely. By understanding XSS prevention, secure file uploads, password hashing, SQL injection protection, and safe file handling practices, developers can build reliable and secure PHP applications.

Practice

Create a secure file upload system that accepts only image files, validates file types and extensions, stores files in an uploads folder, logs upload activity, and prevents XSS by sanitizing all displayed data.

Lecture 14 · Web & Database

MySQL & PDO

Advanced ~60 min

Databases are an essential part of modern web applications. They allow us to store, retrieve, update, and manage data efficiently. Whether you are building a blog, e-commerce website, social media platform, or learning management system, a database is usually required to store application data.

MySQL is one of the most popular relational database management systems (RDBMS) used with PHP. PHP communicates with MySQL through extensions such as PDO (PHP Data Objects), which provides a secure and flexible way to work with databases.

What is MySQL?

MySQL is an open-source relational database management system that stores data in tables consisting of rows and columns. It uses Structured Query Language (SQL) to manage and manipulate data.

MySQL is widely used because it is reliable, fast, scalable, and supported by most hosting providers.

Database Terminology

  • Database – A collection of organized data.
  • Table – Stores related data in rows and columns.
  • Row – A single record in a table.
  • Column – A specific field of information.
  • Primary Key – A unique identifier for each row.
  • Foreign Key – A reference to another table.

Example Database Table

Consider a users table used in a web application.

users

+----+----------+----------------------+
| id | name     | email                |
+----+----------+----------------------+
| 1  | Ahmed    | ahmed@email.com      |
| 2  | Sarah    | sarah@email.com      |
+----+----------+----------------------+

Each row represents a user, and each column stores specific information about that user.

Creating a Database

A database can be created using SQL commands.

CREATE DATABASE learning_php;

After creating a database, tables can be added to store application data.

Creating a Table

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(255)
);

This table contains an auto-incrementing ID, a user name, and an email address.

Introduction to PDO

PDO (PHP Data Objects) is a database abstraction layer that provides a consistent interface for working with different database systems such as MySQL, PostgreSQL, SQLite, and SQL Server.

Instead of writing database-specific code, developers can use PDO methods that work similarly across multiple database engines.

Why Use PDO?

  • Supports multiple database systems.
  • Provides prepared statements.
  • Improves security.
  • Offers better error handling.
  • Encourages cleaner code.
  • Widely used in professional applications.

Connecting to MySQL Using PDO

Before executing queries, a connection must be established.

$host = "localhost";
$dbname = "learning_php";
$username = "root";
$password = "";

$pdo = new PDO(
    "mysql:host=$host;dbname=$dbname",
    $username,
    $password
);

The PDO constructor creates a connection between PHP and the MySQL server.

Handling Connection Errors

Database connections may fail due to incorrect credentials or server issues. Exception handling should always be used.

try {

    $pdo = new PDO(
        "mysql:host=localhost;dbname=learning_php",
        "root",
        ""
    );

} catch (PDOException $e) {

    echo $e->getMessage();
}

Executing Simple Queries

The query() method is useful for executing SQL statements that do not require user input.

$result = $pdo->query(
    "SELECT * FROM users"
);

Fetching Records

Retrieved data can be fetched using different methods.

$users = $result->fetchAll();

print_r($users);

The fetchAll() method retrieves all matching records from the query result.

Prepared Statements

Use PDO with prepared statements for secure database queries.

$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);

Prepared statements separate SQL commands from user-provided data, making applications much more secure.

Why Prepared Statements Matter

One of the biggest security risks in web applications is SQL Injection. Attackers attempt to manipulate SQL queries by inserting malicious input.

// Unsafe
$sql = "SELECT * FROM users WHERE email = '$email'";

If user input is inserted directly into SQL statements, attackers may gain unauthorized access to database records.

// Safe
$stmt = $pdo->prepare(
    "SELECT * FROM users WHERE email = ?"
);

$stmt->execute([$email]);

Inserting Data

Data can be inserted into tables using prepared statements.

$stmt = $pdo->prepare(
    "INSERT INTO users(name, email)
     VALUES (?, ?)"
);

$stmt->execute([
    $name,
    $email
]);

Updating Records

$stmt = $pdo->prepare(
    "UPDATE users
     SET name = ?
     WHERE id = ?"
);

$stmt->execute([
    $name,
    $id
]);

This query updates a user's name based on their unique ID.

Deleting Records

$stmt = $pdo->prepare(
    "DELETE FROM users
     WHERE id = ?"
);

$stmt->execute([$id]);

Records can be removed safely using parameterized queries.

Named Parameters

PDO supports named parameters, which can improve query readability.

$stmt = $pdo->prepare(
    "SELECT * FROM users
     WHERE email = :email"
);

$stmt->execute([
    ':email' => $email
]);

Fetch Modes

PDO provides several fetch modes that determine how data is returned.

$user = $stmt->fetch(
    PDO::FETCH_ASSOC
);
  • FETCH_ASSOC – Associative array.
  • FETCH_NUM – Numeric array.
  • FETCH_OBJ – Object.
  • FETCH_CLASS – Class instance.

Transactions

Transactions allow multiple database operations to be treated as a single unit of work. If one operation fails, all changes can be rolled back.

try {

    $pdo->beginTransaction();

    // Multiple queries

    $pdo->commit();

} catch (Exception $e) {

    $pdo->rollBack();
}

Transactions are commonly used in banking systems, payment processing, and inventory management.

Best Practices

  • Always use prepared statements.
  • Never trust user input.
  • Use exception handling for database operations.
  • Store database credentials securely.
  • Use transactions for critical operations.
  • Validate data before inserting it.
  • Limit database permissions whenever possible.

Real-World Example

Consider a student management system. The database may contain tables such as students, courses, enrollments, and instructors. PDO can be used to safely insert new students, update course information, retrieve records, and generate reports while maintaining security.

Summary

MySQL is a powerful relational database system used to store and manage application data. PDO provides a secure and flexible way to connect PHP applications to databases. By using prepared statements, transactions, exception handling, and proper validation techniques, developers can build secure and reliable database-driven applications.

Practice

Create a student management database using MySQL. Connect to it using PDO, perform CRUD operations (Create, Read, Update, Delete), implement prepared statements, and use transactions for critical database updates.

Lecture 15 · Web & Database

Building REST APIs

Advanced ~45 min

Modern web applications rarely work alone. Mobile applications, frontend frameworks, desktop software, and third-party services often need a way to communicate with a server. REST APIs provide a standardized way for different systems to exchange data over HTTP.

A REST API (Representational State Transfer Application Programming Interface) allows clients to send requests to a server and receive structured responses, usually in JSON format. REST APIs are widely used because they are simple, scalable, and compatible with virtually every programming language.

What is an API?

An API is a set of rules that allows one application to communicate with another. Instead of directly accessing a database, external applications send requests to an API endpoint which processes the request and returns data.

For example:

  • A mobile app requests user information.
  • An e-commerce website retrieves product data.
  • A payment gateway processes transactions.
  • A weather application fetches weather updates.

What is REST?

REST is an architectural style used to design APIs. RESTful APIs use standard HTTP methods such as GET, POST, PUT, and DELETE to perform operations on resources.

A resource can be anything such as:

  • Users
  • Products
  • Orders
  • Courses
  • Students

REST API Structure

GET    /api/users
GET    /api/users/1
POST   /api/users
PUT    /api/users/1
DELETE /api/users/1

Each endpoint represents a resource and each HTTP method performs a specific action.

HTTP Methods

Method Purpose
GET Retrieve data.
POST Create new records.
PUT Update existing records.
DELETE Remove records.

JSON Responses

Most REST APIs exchange data using JSON (JavaScript Object Notation). JSON is lightweight, human-readable, and supported by almost every modern language.

JSON Response

<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');

$users = [['id'=>1, 'name'=>'Ahmed']];
echo json_encode($users);
?>

The json_encode() function converts PHP arrays and objects into JSON format before sending them to the client.

Sample JSON Output

[
    {
        "id": 1,
        "name": "Ahmed"
    }
]

This JSON data can be consumed by mobile applications, JavaScript frontends, or third-party systems.

Receiving JSON Requests

REST APIs often receive JSON data from clients. PHP can read incoming JSON using the special input stream php://input.

$data = json_decode(
    file_get_contents('php://input'),
    true
);

print_r($data);

The second parameter (true) converts JSON objects into associative arrays.

Routing Requests

Routing determines which code executes when a particular URL or HTTP method is requested.

Routing by Method

$method = $_SERVER['REQUEST_METHOD'];
$input = json_decode(file_get_contents('php://input'), true);

switch ($method) {
    case 'GET':
        echo json_encode($db->all());
        break;

    case 'POST':
        $db->insert($input);
        http_response_code(201);
        break;

    case 'DELETE':
        $db->delete($_GET['id']);
        http_response_code(204);
        break;
}

The REQUEST_METHOD variable contains the HTTP method used by the client. This allows a single endpoint to handle multiple operations.

HTTP Status Codes

APIs should always return appropriate status codes so clients understand the result of a request.

Code Meaning
200 Success.
201 Resource created.
204 No content returned.
400 Bad request.
401 Unauthorized.
404 Resource not found.
500 Server error.

Creating Resources with POST

The POST method is used to create new resources.

if ($method === 'POST') {

    $db->insert($input);

    http_response_code(201);

    echo json_encode([
        'message' => 'User Created'
    ]);
}

Updating Resources with PUT

PUT requests are used to modify existing records.

if ($method === 'PUT') {

    $db->update(
        $_GET['id'],
        $input
    );

    echo json_encode([
        'message' => 'User Updated'
    ]);
}

Deleting Resources

DELETE requests remove resources from the system.

if ($method === 'DELETE') {

    $db->delete($_GET['id']);

    http_response_code(204);
}

API Authentication

Most APIs should be protected so only authorized users can access resources. Authentication verifies the identity of a client before allowing requests.

Token Authentication

$token = $_SERVER['HTTP_AUTHORIZATION'] ?? '';

if (!str_starts_with($token, 'Bearer ')) {

    http_response_code(401);

    exit(json_encode([
        'error' => 'Unauthorized'
    ]));
}

Bearer tokens are commonly used in REST APIs because they are simple and work well with web and mobile applications.

What is CORS?

Cross-Origin Resource Sharing (CORS) controls whether browsers allow requests from different domains.

header(
    'Access-Control-Allow-Origin: *'
);

This header allows requests from any domain. In production environments, you should restrict access to trusted domains whenever possible.

Error Responses

APIs should return structured error messages rather than plain text.

http_response_code(404);

echo json_encode([
    'error' => 'User Not Found'
]);

Consistent error formats make API integration easier for client developers.

API Versioning

As APIs evolve, changes may break existing clients. Versioning allows developers to introduce new features while maintaining compatibility.

/api/v1/users
/api/v2/users

API versioning is a common practice in enterprise applications.

REST API Best Practices

  • Use meaningful resource names.
  • Always return JSON responses.
  • Use proper HTTP status codes.
  • Validate all incoming data.
  • Implement authentication.
  • Handle errors consistently.
  • Document endpoints clearly.
  • Use versioning for long-term maintenance.

Real-World Example

Consider an online store API. The frontend application requests product information using GET requests, creates orders using POST requests, updates inventory using PUT requests, and removes discontinued products using DELETE requests. All communication occurs through JSON-based REST endpoints.

Summary

REST APIs are the foundation of modern web development. They enable communication between applications using HTTP methods and JSON data. By implementing proper routing, authentication, validation, status codes, and error handling, developers can create scalable and secure APIs that serve web, mobile, and third-party applications efficiently.

Practice

Build a complete /api/products REST endpoint supporting GET, POST, PUT, and DELETE requests. Return JSON responses, use proper HTTP status codes, validate incoming data, and protect the API using Bearer token authentication.

Lecture 16 · Web & Database

Laravel Basics

Advanced ~45 min

Laravel is one of the most popular PHP frameworks used for building modern, scalable, and secure web applications. It follows the MVC (Model-View-Controller) architecture and provides powerful tools for routing, database management, authentication, validation, caching, APIs, and much more.

Laravel helps developers write clean, maintainable code by providing elegant syntax and a rich ecosystem of built-in features. Many professional companies use Laravel to develop enterprise applications, e-commerce platforms, learning management systems, and REST APIs.

Why Laravel?

While PHP can be used without a framework, Laravel simplifies development by handling many common tasks automatically.

  • Clean and elegant syntax.
  • MVC architecture.
  • Built-in authentication system.
  • Powerful ORM called Eloquent.
  • Database migrations.
  • API development support.
  • Security features.
  • Large community and ecosystem.

What is MVC?

Laravel follows the Model-View-Controller architecture pattern. MVC separates application logic into different layers, making projects easier to manage and maintain.

  • Model – Handles database operations.
  • View – Displays data to users.
  • Controller – Processes requests and coordinates models and views.
User Request
      ↓
Controller
      ↓
Model
      ↓
Database
      ↓
View
      ↓
Response

Install Laravel

Laravel can be installed using Composer. Composer automatically downloads Laravel and all required dependencies.

composer create-project laravel/laravel myapp

cd myapp

php artisan serve
# http://localhost:8000

After installation, the built-in development server can be started using the Artisan command-line tool.

Project Structure

Laravel projects contain several important directories.

myapp/
│
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
├── tests/
└── vendor/
  • app/ – Application logic.
  • routes/ – Route definitions.
  • resources/ – Views and frontend assets.
  • database/ – Migrations and seeders.
  • public/ – Publicly accessible files.

Laravel Artisan

Artisan is Laravel's command-line interface. It provides commands for generating controllers, models, migrations, jobs, events, and many other application components.

php artisan list

This command displays all available Artisan commands.

Routes

Routes determine how Laravel responds to incoming HTTP requests. Route definitions are usually stored inside the routes directory.

// routes/web.php
Route::get('/', fn() => view('welcome'));

Route::get('/users', [UserController::class, 'index']);

Route::resource('posts', PostController::class);

The Route facade allows developers to define endpoints that map URLs to controller methods or closures.

Common Route Types

Route::get('/users', ...);

Route::post('/users', ...);

Route::put('/users/{id}', ...);

Route::delete('/users/{id}', ...);

Different HTTP methods are used for different operations within a web application.

Route Parameters

Route parameters allow dynamic values to be passed through URLs.

Route::get('/users/{id}', function ($id) {
    return $id;
});

Visiting /users/5 would return the value 5.

Controllers

Controllers contain request-handling logic. Instead of placing application logic directly inside routes, Laravel encourages developers to use controllers.

Controller

// php artisan make:controller PostController --resource

class PostController extends Controller {

    public function index() {
        return Post::all();
    }

    public function store(Request $r) {

        $r->validate([
            'title' => 'required'
        ]);

        return Post::create($r->all());
    }
}

Resource controllers provide standardized methods for CRUD operations, making application development faster and more organized.

Generating Controllers

php artisan make:controller UserController

Laravel automatically creates the controller file in the appropriate location.

Views and Blade Templates

Laravel uses the Blade templating engine for creating dynamic HTML pages. Blade provides a clean syntax for displaying data and controlling layouts.

<h1>{{ $title }}</h1>

@if($user)
    Welcome {{ $user->name }}
@endif

Blade automatically escapes output to help prevent XSS attacks.

Eloquent ORM

Eloquent is Laravel's Object Relational Mapper (ORM). It allows developers to work with database records as PHP objects rather than writing raw SQL queries.

Eloquent Model

// php artisan make:model Post -m

class Post extends Model {

    protected $fillable = [
        'title',
        'body'
    ];

    public function user() {
        return $this->belongsTo(User::class);
    }
}

Post::where('published', true)
    ->latest()
    ->take(10)
    ->get();

Eloquent provides a powerful query builder that allows complex database operations to be written using expressive PHP syntax.

Creating Records

Post::create([
    'title' => 'Laravel Basics',
    'body' => 'Learning Eloquent'
]);

The create() method inserts a new record into the database.

Retrieving Records

$posts = Post::all();

$post = Post::find(1);

$publishedPosts = Post::where(
    'published',
    true
)->get();

Eloquent provides multiple methods for retrieving records efficiently.

Updating Records

$post = Post::find(1);

$post->title = "Updated Title";

$post->save();

Deleting Records

$post = Post::find(1);

$post->delete();

Database Migrations

Migrations allow developers to manage database structures using PHP code. Instead of manually creating tables, migrations provide version control for databases.

php artisan make:migration create_posts_table

After creating a migration, run:

php artisan migrate

Relationships

Eloquent makes it easy to define relationships between models.

class User extends Model {

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

A user can have multiple posts, while each post belongs to a single user.

Validation

Laravel provides a powerful validation system that ensures user input meets application requirements before processing.

$request->validate([
    'title' => 'required|min:3',
    'email' => 'required|email'
]);

Laravel Security Features

Laravel includes many built-in security protections.

  • CSRF protection.
  • Password hashing.
  • Input validation.
  • Authentication scaffolding.
  • XSS protection through Blade.
  • SQL Injection protection via Eloquent.

Real-World Example

Consider a blogging platform built with Laravel. Routes define URLs, controllers process requests, models communicate with the database, Blade templates render views, and Eloquent manages relationships between users, posts, comments, and categories.

Best Practices

  • Keep controllers focused and lightweight.
  • Use Eloquent relationships whenever possible.
  • Validate all incoming requests.
  • Use migrations for database changes.
  • Follow Laravel naming conventions.
  • Separate business logic into services when applications grow.

Summary

Laravel is a powerful PHP framework that simplifies web development through MVC architecture, routing, controllers, Blade templates, Eloquent ORM, migrations, and built-in security features. Mastering Laravel enables developers to build modern, maintainable, and scalable web applications much faster than using plain PHP alone.

Practice

Build a Laravel blog application with posts, categories, comments, migrations, controllers, Blade views, and Eloquent relationships. Implement validation and CRUD functionality for all major resources.

Lecture 17 · Web & Database

Authentication & Deployment

Advanced ~45 min

Authentication and deployment are two of the most important stages of web application development. Authentication ensures that users are who they claim to be, while deployment makes an application available to real users on the internet.

In this lecture, you will learn how PHP applications securely handle passwords, sessions, authentication tokens, and deployment to both shared hosting environments and VPS servers.

What is Authentication?

Authentication is the process of verifying a user's identity before granting access to protected resources.

Common authentication methods include:

  • Username and password login.
  • Session-based authentication.
  • JWT token authentication.
  • OAuth authentication.
  • Multi-factor authentication (MFA).

Authentication Workflow

User Login
     ↓
Enter Credentials
     ↓
Server Verification
     ↓
Session / Token Created
     ↓
Access Granted

Once authenticated, the application stores information that identifies the user during future requests.

Password Security

Passwords should never be stored in plain text. If a database is compromised, plain-text passwords can immediately expose user accounts.

PHP provides built-in password hashing functions that automatically use secure hashing algorithms and salting mechanisms.

Password Hashing

// Hash on signup
$hash = password_hash(
    $_POST['password'],
    PASSWORD_DEFAULT
);

// Verify on login
if (
    password_verify(
        $_POST['password'],
        $user->password_hash
    )
) {
    $_SESSION['user_id'] = $user->id;
}

The password_hash() function creates a secure hash, while password_verify() checks whether a provided password matches the stored hash.

Why Hashing is Important

Consider the following unsafe example:

// Never do this
$password = "mypassword123";

If passwords are stored directly, anyone with database access can view them. Hashing converts passwords into irreversible values that cannot easily be recovered.

Using Sessions

Session-based authentication is commonly used in traditional web applications. After a successful login, PHP stores information inside a session.

session_start();

$_SESSION['user_id'] = 5;

The session data remains available until the user logs out or the session expires.

Checking Authentication

session_start();

if (!isset($_SESSION['user_id'])) {

    header("Location: login.php");

    exit;
}

This ensures that only authenticated users can access protected pages.

Logging Out Users

Logging out typically involves destroying the current session.

session_start();

session_destroy();

header("Location: login.php");

Session Security

To reduce session hijacking risks, regenerate session IDs after login.

session_start();

session_regenerate_id(true);

This creates a new session identifier and invalidates the previous one.

Introduction to JWT

JWT (JSON Web Token) is a compact authentication mechanism commonly used in REST APIs and mobile applications.

Unlike sessions, JWTs are stored on the client side and sent with every request.

JWT Structure

HEADER.PAYLOAD.SIGNATURE
  • Header – Token type and algorithm.
  • Payload – User information and claims.
  • Signature – Security verification.

JWT Tokens

// composer require firebase/php-jwt

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$payload = [
    'user_id' => 1,
    'exp' => time() + 3600
];

$jwt = JWT::encode(
    $payload,
    $secret,
    'HS256'
);

// Decode
$decoded = JWT::decode(
    $jwt,
    new Key($secret, 'HS256')
);

The token contains encoded user information and an expiration time.

JWT Authentication Flow

User Login
      ↓
Credentials Verified
      ↓
JWT Generated
      ↓
Client Stores Token
      ↓
Token Sent With Requests
      ↓
Server Validates Token

Authorization Header

JWT tokens are usually transmitted using the Authorization header.

Authorization: Bearer eyJhbGciOi...

The server validates the token before allowing access to protected resources.

Authentication Best Practices

  • Always hash passwords.
  • Use HTTPS in production.
  • Regenerate session IDs after login.
  • Set token expiration times.
  • Validate all authentication tokens.
  • Implement account lockout protection.
  • Use multi-factor authentication when possible.

What is Deployment?

Deployment is the process of moving an application from a development environment to a live server where users can access it through the internet.

Before deployment, applications should be tested thoroughly to ensure functionality, security, and performance.

Deployment Checklist

  • Configure production database.
  • Enable HTTPS.
  • Set secure environment variables.
  • Disable debugging mode.
  • Optimize application performance.
  • Create backups.
  • Test authentication features.

Deploy to Shared Hosting

Shared hosting is often the simplest and most affordable deployment option for small PHP applications.

# Upload via FTP/SFTP
# Set document root to /public
# Configure .htaccess for clean URLs
# Update .env with production database

Many hosting providers include PHP, MySQL, email services, and file management tools.

Understanding .env Files

Environment files store sensitive configuration values separately from code.

DB_HOST=localhost
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=secret

Environment variables should never be committed to public repositories.

Deploy to VPS

A VPS (Virtual Private Server) provides greater flexibility and control compared to shared hosting.

# Ubuntu + Nginx + PHP-FPM

sudo apt install nginx php-fpm php-mysql composer

sudo nano /etc/nginx/sites-available/myapp

# Set fastcgi_pass to PHP-FPM

sudo systemctl restart nginx

VPS environments are commonly used for medium and large-scale applications.

Nginx and PHP-FPM

Nginx acts as the web server while PHP-FPM processes PHP requests efficiently. This combination is widely used in production environments.

Browser
   ↓
Nginx
   ↓
PHP-FPM
   ↓
PHP Application
   ↓
Database

Production Security

Security becomes even more important once an application is publicly accessible.

  • Disable error display.
  • Use firewall protection.
  • Restrict SSH access.
  • Use strong database credentials.
  • Install SSL certificates.
  • Keep software updated.

Monitoring and Logging

Production applications should log important events and errors. Logs help identify bugs, performance issues, and security threats.

error_log(
    "User login successful"
);

Backup Strategies

Regular backups protect applications against accidental deletion, server failures, and security incidents.

  • Database backups.
  • Application file backups.
  • Configuration backups.
  • Automated backup schedules.

Real-World Example

Consider an online learning platform. Users authenticate using securely hashed passwords and JWT tokens. The application runs on a VPS with Nginx, PHP-FPM, and MySQL. HTTPS protects communication while automated backups ensure data safety.

Summary

Authentication verifies user identities and protects application resources. PHP provides secure tools such as password_hash(), password_verify(), sessions, and JWT authentication. After development is complete, applications can be deployed to shared hosting or VPS servers where security, monitoring, backups, and performance optimization become essential for long-term success.

Practice

Add secure authentication to your application using password hashing, session management, and JWT tokens. Deploy the application to a VPS, configure Nginx and PHP-FPM, enable HTTPS, and implement automated backups.

Lecture 18 · Capstone

Capstone Project: Blog System

Advanced ~180 min

Congratulations! You have reached the final project of this PHP course. This capstone project combines everything you have learned throughout the course, including PHP fundamentals, Object-Oriented Programming, MySQL, PDO, authentication, file uploads, security, and application architecture.

Your goal is to build a complete blog management system where users can register, log in, create blog posts, upload images, edit content, manage posts, and store data securely in a database.

This project simulates a real-world web application and will help reinforce the practical skills required to build professional PHP applications.

Project Overview

The Blog System should allow users to:

  • Create an account.
  • Log into the application.
  • Create blog posts.
  • Edit existing posts.
  • Delete posts.
  • Upload post images.
  • View posts from other users.
  • Manage their profile.

Project Requirements

// Project requirements:
// 1. Database schema for users and posts
// 2. Login/Register system
// 3. Post CRUD functionality
// 4. File uploads for post images

These requirements form the foundation of the application. Additional features can be added as bonus challenges after completing the core functionality.

Application Features

  • User Registration.
  • User Login.
  • User Logout.
  • Password Hashing.
  • Session Authentication.
  • Create Posts.
  • Read Posts.
  • Update Posts.
  • Delete Posts.
  • Image Upload Support.
  • Profile Management.
  • Database Integration.

Project Structure

Organizing files properly is important for maintainability.

blog-system/
│
├── config/
│   └── database.php
│
├── classes/
│   ├── User.php
│   ├── Post.php
│   └── Auth.php
│
├── uploads/
│
├── views/
│
├── assets/
│
├── login.php
├── register.php
├── dashboard.php
├── create-post.php
├── edit-post.php
├── delete-post.php
└── index.php

Database Design

A well-designed database is the backbone of any application.

Users Table

CREATE TABLE users (

    id INT AUTO_INCREMENT PRIMARY KEY,

    name VARCHAR(100),

    email VARCHAR(255) UNIQUE,

    password_hash VARCHAR(255),

    created_at TIMESTAMP
);

This table stores information about registered users.

Posts Table

CREATE TABLE posts (

    id INT AUTO_INCREMENT PRIMARY KEY,

    user_id INT,

    title VARCHAR(255),

    content TEXT,

    image VARCHAR(255),

    created_at TIMESTAMP,

    FOREIGN KEY (user_id)
    REFERENCES users(id)
);

Each post belongs to a user through the user_id foreign key.

Application Workflow

User Registers
      ↓
User Logs In
      ↓
Session Created
      ↓
Create Post
      ↓
Save to Database
      ↓
Display on Homepage

User Registration

The registration system should allow new users to create accounts securely.

$hash = password_hash(
    $_POST['password'],
    PASSWORD_DEFAULT
);

$stmt = $pdo->prepare(
    "INSERT INTO users
     (name, email, password_hash)
     VALUES (?, ?, ?)"
);

$stmt->execute([
    $name,
    $email,
    $hash
]);

Passwords should always be hashed before being stored in the database.

User Login

Users must authenticate before accessing protected pages.

if (
    password_verify(
        $_POST['password'],
        $user['password_hash']
    )
) {

    $_SESSION['user_id'] =
        $user['id'];
}

Authentication Middleware

Protected pages should verify that users are logged in before displaying content.

session_start();

if (!isset($_SESSION['user_id'])) {

    header("Location: login.php");

    exit;
}

Creating Posts

Authenticated users should be able to publish new blog posts.

$stmt = $pdo->prepare(
    "INSERT INTO posts
     (user_id, title, content)
     VALUES (?, ?, ?)"
);

$stmt->execute([
    $_SESSION['user_id'],
    $title,
    $content
]);

Displaying Posts

Blog posts should be displayed on the homepage.

$posts = $pdo
    ->query("SELECT * FROM posts")
    ->fetchAll();

Each post can be displayed inside a card layout containing the title, image, author information, and content preview.

Editing Posts

$stmt = $pdo->prepare(
    "UPDATE posts
     SET title = ?, content = ?
     WHERE id = ?"
);

$stmt->execute([
    $title,
    $content,
    $id
]);

Users should only be allowed to edit their own posts.

Deleting Posts

$stmt = $pdo->prepare(
    "DELETE FROM posts
     WHERE id = ?"
);

$stmt->execute([$id]);

File Uploads

Blog posts often contain featured images. Users should be able to upload images safely.

move_uploaded_file(
    $_FILES['image']['tmp_name'],
    "uploads/" .
    $_FILES['image']['name']
);

Always validate file types and extensions before storing uploaded files.

Image Validation

$allowed = [
    'jpg',
    'jpeg',
    'png'
];

$ext = strtolower(
    pathinfo(
        $_FILES['image']['name'],
        PATHINFO_EXTENSION
    )
);

if (
    in_array($ext, $allowed)
) {
    // Upload file
}

Search Feature (Optional)

Enhance the blog system by allowing users to search for posts.

$stmt = $pdo->prepare(
    "SELECT *
     FROM posts
     WHERE title LIKE ?"
);

$stmt->execute([
    "%$keyword%"
]);

Categories Feature (Optional)

Categories help organize blog content.

Technology
Programming
Design
Business
Education

Security Checklist

  • Use prepared statements.
  • Hash passwords.
  • Validate user input.
  • Sanitize output using htmlspecialchars().
  • Protect pages with authentication.
  • Validate uploaded files.
  • Use secure session management.

Testing Your Application

Before deployment, thoroughly test every feature.

  • User registration.
  • User login.
  • User logout.
  • Post creation.
  • Post editing.
  • Post deletion.
  • Image uploads.
  • Database connectivity.
  • Error handling.

Deployment Goals

Once development is complete, deploy the application to a live server.

  • Configure production database.
  • Enable HTTPS.
  • Upload project files.
  • Secure configuration settings.
  • Test all routes and features.

Bonus Challenges

  • Add comments to blog posts.
  • Add likes and reactions.
  • Create an admin dashboard.
  • Implement REST API endpoints.
  • Add email verification.
  • Add password reset functionality.
  • Implement pagination.
  • Add post categories and tags.

Learning Outcomes

By completing this capstone project, you will gain hands-on experience with:

  • PHP Programming.
  • Object-Oriented Development.
  • MySQL Databases.
  • PDO and Prepared Statements.
  • Authentication Systems.
  • File Upload Handling.
  • Application Security.
  • Project Architecture.
  • Deployment Techniques.

Final Summary

This Blog System capstone project serves as a complete practical application of everything learned throughout the course. By building authentication, database integration, CRUD functionality, image uploads, and secure user management, you will create a professional-grade PHP application that closely resembles real-world projects developed in the industry.

Final Challenge

Build the complete Blog System from scratch. Implement user registration, login, authentication, CRUD operations, image uploads, security validation, and deployment. Then extend the application with at least three bonus features such as comments, categories, likes, REST APIs, or an admin panel.