Introduction to PHP & Setup
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\htdocsfolder (on Windows) or/Applications/XAMPP/htdocs(on Mac). - Create a new folder for your project (e.g.,
php_mastery) insidehtdocs. - 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.
<?php // This is a PHP comment echo ("Hello, PHP Mastery!"); echo (" 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:
<?php
phpinfo();
?>
When you run this file, it will display a detailed page showing your PHP version and all enabled modules.
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.
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.
Variables & Data Types
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.
$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:
$nameor$_userare valid;$1nameis NOT. - Case-Sensitivity:
$ageand$AGEare 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
trueorfalse.
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.
$age = 25; $name = "Alice"; var_dump($age); // Output: int(25) var_dump($name); // Output: string(5) "Alice"
Create a PHP script that defines the following variables:
- A string for your favorite movie.
- An integer for the release year.
- A float for the IMDB rating.
- A boolean for whether you have seen it more than once.
var_dump() on each variable to verify their data types in the browser.
Operators & Expressions
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)
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.
$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.)
$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.
$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.
$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.
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".
Control Flow
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
$ageis 18 or greater, the program printsAdult - 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
breakin switch statements - Using incorrect logical operators
Best Practices
- Keep conditions readable
- Avoid deeply nested logic
- Use meaningful variable names
- Prefer
foreachfor 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
foreachloop 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
Loops
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.
// 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.
$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.
$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
$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.
$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.
for ($i = 0; $i < 10; $i++) { if ($i == 3) continue; // Skip number 3 if ($i == 7) break; // Stop loop at 7 echo $i; }
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]".
Functions
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:
sumis the function name.$aand$bare parameters.returnsends 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
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.
Arrays & Superglobals
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
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.
Strings & Forms
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()
Sessions & Cookies
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
- User visits the website
- PHP creates a unique session ID
- The ID is stored in the browser
- Session data is stored on the server
- 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
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
Object-Oriented PHP
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; } }
Namespaces & Composer
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.
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.
Exceptions & Error Handling
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.
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.
File I/O & Security
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.
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.
MySQL & PDO
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.
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.
Building REST APIs
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.
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.
Laravel Basics
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.
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.
Authentication & Deployment
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.
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.
Capstone Project: Blog System
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.
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.