↑
Introduction
Hello World
Variables
Constants
Comments
var_dump
Data Types
Control Flow
Functions
Advanced Functions
Arrays
Advanced Array Operations
Organizing Files
State Management
Processing Forms
Working with Files
Date and Time
Namespaces
Introduction to PHP
What Is PHP?
PHP stands for Hypertext Preprocessor .
It is a widely used server-side scripting language designed specifically for web development.
PHP code is executed on the server and generates HTML, JSON, or other output that is sent to the client.
How PHP Works
PHP runs on a server with a PHP interpreter (e.g., Apache + PHP, Nginx + PHP-FPM).
When a user requests a .php file:
the server executes the PHP code
generates HTML (or other data)
sends the result to the browser
Browser ---> Request ---> Server (PHP engine) ---> Output HTML ---> Browser
Your First PHP Script
PHP code is placed inside <?php ... ?> tags.
<?php
echo "Hello, World!";
?>
If saved as index.php and placed on a server, the browser will display Hello, World! .
Embedding PHP in HTML
PHP can be mixed directly with HTML documents.
<html>
<body>
<h1>Welcome</h1>
<p>The time is: <?php echo date("H:i:s"); ?></p>
</body>
</html>
When processed by the server, the output will be pure HTML with the date filled in.
PHP Variables
All variables in PHP start with a dollar sign ($).
<?php
$name = "Junzhe";
$age = 22;
echo "Name: $name, Age: $age";
?>
Basic Data Types
Type
Description
String
Text data
Integer
Whole numbers
Float
Decimal numbers
Boolean
true or false
Array
List or dictionary-like collections
Object
Instances of classes
NULL
No value
PHP Arrays
<?php
$colors = ["red", "green", "blue"];
$person = ["name" => "Alice", "age" => 30];
?>
Control Structures
<?php
if ($age >= 18) {
echo "Adult";
} else {
echo "Minor";
}
for ($i = 0; $i < 3; $i++) {
echo $i;
}
?>
Functions
<?php
function greet($name) {
return "Hello, $name!";
}
echo greet("Junzhe");
?>
Working with Forms
PHP is often used to process form input.
<form method="POST">
Name: <input name="name">
<input type="submit">
</form>
<?php
if ($_POST) {
echo "Hello " . $_POST["name"];
}
?>
Connecting to Databases
<?php
$pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass");
$stmt = $pdo->query("SELECT * FROM users");
foreach ($stmt as $row) {
echo $row["name"];
}
?>
Why PHP Is Still Popular
Runs on nearly all hosting services.
Powers major platforms:
WordPress
MediaWiki (Wikipedia)
Drupal
Huge ecosystem and long history.
Popular Frameworks
Framework
Purpose
Laravel
Modern MVC, expressive syntax
Symfony
Enterprise-level framework
CodeIgniter
Lightweight, simple
Yii
Fast, component-based
Summary
Feature
Description
Server-side scripting
PHP runs on the server to generate web content
Embedded HTML
Mix PHP directly with HTML
Database support
Works with MySQL, PostgreSQL, SQLite, etc.
Variables start with $
Simplifies syntax
Widely supported
Available on almost all hosting services
Large ecosystem
WordPress, Laravel, Symfony, Drupal
Hello World in PHP
Introduction
Writing “Hello World” is the simplest way to test that PHP is installed and working correctly.
PHP scripts run on the server, and the output is sent to the browser as plain text or HTML.
In PHP, output is usually produced using the echo or print statements.
Basic Hello World Example
Create a file called hello.php with the following content:
<?php
echo "Hello, World!";
?>
When executed by PHP, the browser will display:
Hello, World!
Embedding Hello World in HTML
PHP is designed to be embedded in HTML pages.
PHP blocks run only inside <?php ... ?>.
<!DOCTYPE html>
<html>
<body>
<h1>My First PHP Page</h1>
<p>
<?php echo "Hello from PHP!"; ?>
</p>
</body>
</html>
Hello World Using print
print is similar to echo, but slightly slower and returns a value (which you rarely use).
<?php
print "Hello using print!";
?>
Hello World on Command Line (CLI)
You can run PHP scripts directly from the terminal without a web server.
Save the file then run:
php hello.php
Hello, World!
Ensuring PHP Is Installed
Use the terminal to verify that PHP is available:
php -v
You should see a version like:
PHP 8.4.14 (cli) ...
Running Hello World with a Built-in PHP Server
PHP includes a simple development server. Useful for quick tests.
Run from inside your project folder:
php -S localhost:8000
http://localhost:8000/hello.php
Short Open Tags (Deprecated/Less Recommended)
Some older PHP code uses <? echo "Hello"; ?>.
These may be disabled on some servers.
Use the full form <?php ... ?> for compatibility.
Summary
Concept
Description
Hello World file
echo "Hello, World!";
Embedded PHP
Use <?php ... ?> inside HTML
CLI execution
Run php hello.php in terminal
Built-in server
php -S localhost:8000
echo vs print
echo is slightly faster; both output text
Short tags
Not recommended; use full <?php tag
PHP Variables
What Is a Variable in PHP?
A variable in PHP is a named container that holds a value in memory (number, string, array, object, etc.).
Variables are mutable , which means you can change their value at any time.
PHP is a dynamically typed language:
The type of a variable is determined at runtime by the assigned value.
The same variable can hold different types at different times.
All variables in PHP start with a $ sign.
Basic Syntax and Naming Rules
Dynamic Types: Changing the Value Type
PHP allows the same variable to hold values of different types over time:
<?php
$value = 42; // integer
$value = "Hello"; // now string
$value = 3.14; // now float
$value = true; // now boolean
?>
Common scalar types:
integer: whole numbers (1, -5)
float (double): decimal numbers (3.14)
string: text ("Hello", 'World')
boolean: true or false
PHP automatically converts between types in many operations (type juggling):
<?php
$x = "10"; // string
$y = 5; // integer
$sum = $x + $y; // PHP converts "10" to int, result 15
?>
You can explicitly cast types:
<?php
$number = "42";
$intNumber = (int)$number; // 42 as integer
$floatNumber = (float)$number; // 42.0 as float
?>
Strings and Variable Interpolation
PHP has two common string syntaxes: single quotes : '...' and double quotes : "..."
Variables are interpolated only in double-quoted strings:
<?php
$name = "Alice";
echo "Hello, $name"; // Hello, Alice
echo 'Hello, $name'; // Hello, $name
?>
For clarity, you can use curly braces:
<?php
$language = "PHP";
echo "I like {$language} variables."; // I like PHP variables.
?>
Concatenation uses . (dot) operator:
<?php
$firstName = "Ada";
$lastName = "Lovelace";
$fullName = $firstName . " " . $lastName;
echo $fullName; // Ada Lovelace
?>
Arrays, Objects, and NULL
Arrays are flexible collections (indexed or associative):
<?php
$numbers = [1, 2, 3]; // indexed array
$user = [
"name" => "Alice",
"age" => 25,
];
?>
Objects are instances of classes:
<?php
class Person {
public string $name;
}
$p = new Person();
$p->name = "Bob";
?>
NULL / null represents “no value”:
<?php
$something = null; // variable exists but has no value
?>
An unset variable is different from NULL:
<?php
unset($something); // removes the variable
?>
Assignment by Value vs. Assignment by Reference
Variable Scope: Local, Global, Static
Local scope : variables declared inside a function are visible only within that function:
<?php
$outside = 1;
function demo() {
$inside = 2;
echo $inside; // ok
// echo $outside; // undefined inside function (without global)
}
?>
Global scope : variables defined outside functions are global, but not automatically visible inside functions.
To access a global variable inside a function, use global keyword or $GLOBALS:
<?php
$counter = 0;
function increment() {
global $counter;
$counter++;
}
increment();
echo $counter; // 1
?>
Static variables inside functions preserve their value between calls:
<?php
function nextId() {
static $id = 0; // initialized only once
$id++;
return $id;
}
echo nextId(); // 1
echo nextId(); // 2
echo nextId(); // 3
?>
Prefer passing variables as parameters instead of using global for cleaner code.
Superglobal Variables
Variable Variables (Advanced)
Checking and Debugging Variables
Check if a variable is set:
<?php
if (isset($x)) {
echo "x is set";
}
?>
Check if a variable is null:
<?php
if (is_null($value)) {
echo "value is null";
}
?>
Check type:
<?php
is_int($x);
is_string($x);
is_array($x);
is_bool($x);
?>
Quickly inspect value and type:
<?php
var_dump($x);
print_r($array);
?>
PHP Constants
What Is a Constant in PHP?
A constant in PHP is a named value that cannot change once it is defined.
Constants are often used for:
configuration values (database host, API keys),
fixed numbers (PI, statuses),
paths and environment flags.
Unlike variables:
constants do not start with $,
are automatically global in scope,
cannot be reassigned.
Defining Constants with define()
Traditional way to define constants is the define() function:
Syntax:
<?php
define("PI", 3.14159);
define("APP_NAME", "MyApp");
?>
Usage (no $ sign):
<?php
echo PI; // 3.14159
echo APP_NAME; // MyApp
?>
By default, constant names are case-sensitive :
<?php
define("FOO", 10);
echo FOO; // 10
// echo foo; // undefined constant (notice/error)
?>
In older PHP versions, define() allowed a case-insensitive option, but this is deprecated and should be avoided.
Defining Constants with const
Allowed Values for Constants
Constants can store:
scalar values: int, float, string, bool,
arrays (from PHP 5.6+ with const/define),
from PHP 7.0+, also expressions composed of constants.
Examples:
<?php
const MAX_ITEMS = 100;
const DEBUG_MODE = true;
const PI = 3.14159;
const COLORS = ["red", "green", "blue"];
define("HOST", "localhost");
define("FLAGS", ["DEBUG" => true, "CACHE" => false]);
?>
Constant values must be known at declaration time (no runtime function calls inside const in older versions).
Constant Naming Conventions
Common conventions:
Avoid naming collisions by using prefixes (e.g., APP_*, MYPROJECT_*) in shared environments.
Global Scope of Constants
Checking Constants: defined() and constant()
You can check whether a constant exists using defined():
Example:
<?php
if (!defined("APP_ENV")) {
define("APP_ENV", "production");
}
echo APP_ENV; // production
?>
You can retrieve a constant by name (string) using constant():
<?php
define("SITE_NAME", "MySite");
$name = "SITE_NAME";
echo constant($name); // MySite
?>
constant() is useful when the constant name is dynamic (decided at runtime).
Magic Constants
Class Constants
Constants can also be declared inside classes using const:
Example:
<?php
class Status {
public const ACTIVE = 1;
public const INACTIVE = 0;
}
echo Status::ACTIVE; // 1
?>
Notes:
Accessed with ClassName::CONSTANT_NAME.
They do not use $.
They are shared by all instances of the class (no per-object variation).
Visibility (from PHP 7.1+): You can use public, protected, or private for class constants.
Example with visibility:
<?php
class Config {
public const NAME = "MyApp";
private const SECRET_KEY = "123456";
}
echo Config::NAME; // OK
// echo Config::SECRET_KEY; // error: cannot access private constant
?>
Constants and Namespaces
Single-Line Comments
Multi-Line Comments
Inline Comments
PHPDoc Comments (Documentation Comments)
PHP uses a special comment style for documentation called PHPDoc.
PHPDoc uses:
<?php
/**
* Documentation text.
*/
?>
Commonly used for:
functions and methods,
classes and interfaces,
properties,
modules and files.
Example documenting a function:
<?php
/**
* Add two numbers together.
*
* @param int $x First number
* @param int $y Second number
* @return int Sum of x and y
*/
function add(int $x, int $y): int {
return $x + $y;
}
?>
PHPDoc tags include:
@param
@return
@var
@throws
@deprecated
@see
@author
PHP var_dump
What Is var_dump?
Basic Examples
Dumping Arrays
Example:
<?php
$nums = [1, 2, 3];
var_dump($nums);
?>
Typical output:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
var_dump shows:
the number of elements (array(3))
each key and value
nested arrays recursively
Associative arrays:
<?php
$user = [
"name" => "Alice",
"age" => 25,
];
var_dump($user);
?>
Dumping Objects
Dumping NULL and Empty Values
NULL:
<?php
var_dump(null);
?>
Output:
NULL
Empty array:
<?php
var_dump([]);
?>
Output:
array(0) {
}
Empty string:
<?php
var_dump("");
?>
Output:
string(0) ""
Dumping Multiple Values at Once
You can dump several values in one call:
<?php
var_dump(123, "abc", [1,2], false);
?>
Each argument is dumped sequentially.
Using var_dump in Browser vs CLI
var_dump vs print_r vs var_export
Using ob_start to Capture var_dump Output
Formatting var_dump Output for Readability
Common Use Cases for var_dump
Debugging API responses :
<?php
$response = json_decode($json, true);
var_dump($response);
?>
Checking form submission data :
<?php
var_dump($_POST);
?>
Inspecting objects returned by frameworks (Laravel, Symfony, etc.).
Debugging database results :
<?php
var_dump($stmt->fetchAll());
?>
Checking nested data structures before implementing logic.
PHP Data Types
Overview of PHP Data Types
Boolean Type (bool)
Integer Type (int)
Float Type (float or double)
String Type (string)
Represents sequences of characters.
Strings can be created using:
single quotes: 'Hello'
double quotes: "Hello" (supports interpolation)
heredoc syntax
nowdoc syntax
Examples:
<?php
$name = "Alice";
$message = "Hello, $name"; // interpolation
$raw = 'Hello, $name'; // literal
?>
Heredoc:
<?php
$text = <<<MSG
Line 1
Line 2
MSG;
?>
Nowdoc (no interpolation):
<?php
$text = <<<'MSG'
Literal $content
MSG;
?>
String length is shown in var_dump:
string(5) "Hello"
Array Type (array)
PHP arrays are ordered maps (key–value pairs):
keys may be integers or strings,
arrays may nest arbitrarily.
Examples:
<?php
$numbers = [1, 2, 3];
$user = [
"name" => "Alice",
"age" => 25,
];
?>
Nested array:
<?php
$matrix = [
[1, 2],
[3, 4],
];
?>
var_dump shows depth, count, and structure.
Object Type (object)
Callable Type (callable)
Resource Type (resource)
NULL Type (null)
Type Juggling (Automatic Type Conversion)
PHP automatically converts types depending on context.
Example:
<?php
echo "10" + 5; // 15
echo 10 . " apples"; // "10 apples"
?>
Loose comparisons (==) perform type juggling:
<?php
var_dump("0" == 0); // true
var_dump(false == 0); // true
var_dump("10" == 10); // true
?>
Strict comparisons (===) check both type and value:
<?php
var_dump("10" === 10); // false
?>
Type Casting
Checking Types
Best Practices for Using PHP Data Types
PHP Control Flow
Conditional Statements: if, elseif, else
Basic structure:
<?php
if ($x > 0) {
echo "Positive";
} elseif ($x < 0) {
echo "Negative";
} else {
echo "Zero";
}
?>
The condition must evaluate to a boolean value (true / false).
PHP uses common truthiness rules:
0, "", null, [] are falsy
non-empty strings, non-zero numbers are truthy
Nested conditions:
<?php
if ($isAdmin) {
if ($isLogged) {
echo "Welcome, admin!";
}
}
?>
Ternary Operator (?:)
Short form of if...else:
<?php
$message = ($age >= 18) ? "Adult" : "Minor";
?>
Nested ternaries are possible but should be avoided for readability.
Short ternary (PHP 5.3+):
<?php
$value = $input ?: "default";
?>
Null coalescing operator (PHP 7+):
<?php
$username = $_GET["user"] ?? "Guest";
?>
Null coalescing works without warnings even if key does not exist.
switch Statement
switch matches a value against multiple case labels:
<?php
switch ($day) {
case "Mon":
echo "Monday";
break;
case "Tue":
echo "Tuesday";
break;
default:
echo "Unknown";
}
?>
Switch uses loose comparison (==) unless strict comparisons are used manually.
break is required to prevent fall-through.
Fall-through behavior:
<?php
switch ($n) {
case 1:
case 2:
case 3:
echo "Low number";
break;
}
?>
continue inside switch works differently: it continues an outer loop.
match Expression (PHP 8+)
match is a safer, expression-based alternative to switch.
Features:
strict comparison (===)
returns a value
no break needed
no fall-through
Example:
<?php
$label = match ($status) {
200 => "OK",
404 => "Not Found",
500 => "Server Error",
default => "Unknown",
};
?>
while Loop
Repeats as long as the condition is true.
<?php
$i = 0;
while ($i < 5) {
echo $i;
$i++;
}
?>
If the condition is initially false, the loop body never runs.
Be careful to avoid infinite loops.
do...while Loop
Ensures the loop body runs at least once:
<?php
$i = 0;
do {
echo $i;
$i++;
} while ($i < 5);
?>
Difference from while:
while checks before executing,
do...while checks after executing.
for Loop
<?php
for ($i = 0; $i < 5; $i++) {
echo $i;
}
?>
Typical components:
initialization: $i = 0
condition: $i < 5
increment: $i++
All parts may be omitted:
<?php
for (;;) {
break; // infinite loop without condition
}
?>
foreach Loop
Used to iterate arrays and objects.
<?php
$colors = ["red", "green", "blue"];
foreach ($colors as $c) {
echo $c;
}
?>
With keys:
<?php
foreach ($user as $key => $value) {
echo "$key: $value\n";
}
?>
foreach does not modify the original array unless using references:
<?php
foreach ($numbers as &$n) {
$n *= 2;
}
?>
Be careful when using references — unset the reference afterwards:
<?php
unset($n);
?>
break and continue
break stops execution of the current loop or switch.
<?php
for ($i = 0; $i < 10; $i++) {
if ($i == 5) break;
}
?>
continue skips to the next iteration.
<?php
for ($i = 0; $i < 10; $i++) {
if ($i % 2 == 0) continue;
echo $i;
}
?>
You may specify a numeric argument to break out of multiple nested loops:
<?php
while ($a) {
while ($b) {
break 2; // exits two loops
}
}
?>
return Statement
Ends function execution and optionally returns a value.
<?php
function sum($x, $y) {
return $x + $y;
}
?>
return cannot be used outside of functions or methods.
Exception Handling (try, catch, finally)
Exceptions allow handling error conditions in a controlled way.
<?php
try {
riskyFunction();
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
} finally {
echo "Cleanup tasks";
}
?>
finally always executes, regardless of success or error.
Multiple catch blocks are allowed:
<?php
try {
foo();
} catch (RuntimeException $e) {
// runtime error
} catch (Exception $e) {
// general error
}
?>
Alternative Syntax for Control Structures (Useful in HTML)
When embedding PHP in HTML, you can use the alternative syntax:
<?php if ($loggedIn): ?>
<p>Welcome back</p>
<?php else: ?>
<p>Please log in</p>
<?php endif; ?>
This avoids mixing braces with HTML, improving readability.
Also works for loops:
<?php foreach ($items as $it): ?>
<li><?= $it ?></li>
<?php endforeach; ?>
PHP Functions
What Is a Function in PHP?
Defining a Function
Function Parameters
Functions can accept parameters (inputs).
<?php
function greet($name) {
echo "Hello, $name!";
}
greet("Alice");
?>
PHP parameters are traditionally passed by value , which means modifying the parameter does not affect the original variable
Passing by reference:
<?php
function increment(&$x) {
$x++;
}
$a = 5;
increment($a);
echo $a; // 6
?>
Default Parameter Values
You can specify default values for parameters.
<?php
function connect($host = "localhost") {
echo "Connecting to $host";
}
connect(); // localhost
connect("example"); // custom host
?>
Default values must be:
constants,
literals,
arrays,
not expressions requiring runtime evaluation.
Type Declarations for Parameters and Return Types
PHP supports type declarations:
int
float
string
bool
array
callable
object
class / interface types
mixed (PHP 8)
never (PHP 8.1)
Example with type hint and return type:
<?php
function sum(int $a, int $b): int {
return $a + $b;
}
?>
?int means nullable integer:
<?php
function getId(): ?int {
return null;
}
?>
Returning Values
Use return to give a value back to the caller.
<?php
function square($x) {
return $x * $x;
}
echo square(4); // 16
?>
If no return is given, the function returns null.
Variable-Length Argument Lists
PHP supports variadic functions using ....
Example:
<?php
function sumAll(...$nums) {
$total = 0;
foreach ($nums as $n) {
$total += $n;
}
return $total;
}
echo sumAll(1, 2, 3, 4); // 10
?>
You can mix regular and variadic parameters:
<?php
function logMessage($level, ...$messages) {
foreach ($messages as $m) {
echo "[$level] $m\n";
}
}
?>
Anonymous Functions (Closures)
Anonymous functions have no name and can be stored in variables.
<?php
$double = function($x) {
return $x * 2;
};
echo $double(5); // 10
?>
Closures can capture variables using use:
<?php
$factor = 3;
$mul = function($x) use ($factor) {
return $x * $factor;
};
echo $mul(4); // 12
?>
Arrow Functions (PHP 7.4+)
Short syntax for simple anonymous functions.
<?php
$double = fn($x) => $x * 2;
echo $double(10); // 20
?>
Automatically capture variables from outer scope (by value ).
Useful for array operations:
<?php
$result = array_map(fn($n) => $n * 2, [1,2,3]);
?>
Named Arguments (PHP 8+)
Call a function specifying argument names:
<?php
function createUser($name, $age, $role = "user") {}
createUser(
age: 25,
name: "Alice",
role: "admin"
);
?>
Named arguments improve readability and reduce order dependence.
Recursive Functions
A function can call itself.
Example: factorial
<?php
function fact($n) {
if ($n == 0) return 1;
return $n * fact($n - 1);
}
?>
Important:
must have a stopping condition,
deep recursion may hit PHP recursion limits.
Function Existence and Dynamic Calls
Check if a function exists:
<?php
if (function_exists("foo")) {
foo();
}
?>
Call a function dynamically using a string:
<?php
function hello() { echo "Hello"; }
$fn = "hello";
$fn(); // calls hello()
?>
Call functions/methods via call_user_func:
<?php
call_user_func("hello");
?>
Global Variables Inside Functions
Variables inside functions are local by default.
Use global to access globals:
<?php
$a = 10;
function show() {
global $a;
echo $a;
}
?>
Alternatively use $GLOBALS array.
Static Variables Inside Functions
static preserves values across calls:
<?php
function counter() {
static $x = 0;
$x++;
return $x;
}
echo counter(); // 1
echo counter(); // 2
echo counter(); // 3
?>
Useful for caching or iterative state.
PHP Advanced Functions
Higher-Order Functions (Functions That Take Functions)
A higher-order function is a function that:
accepts another function as an argument,
returns a function.
Example: applying a callback to each element:
<?php
function apply(array $items, callable $fn): array {
$result = [];
foreach ($items as $it) {
$result[] = $fn($it);
}
return $result;
}
print_r(apply([1,2,3], fn($x) => $x * 2));
?>
A function returning another function:
<?php
function multiplier($factor): callable {
return fn($x) => $x * $factor;
}
$times3 = multiplier(3);
echo $times3(10); // 30
?>
Closures with use
Closures can capture outer-scope variables using use.
<?php
$prefix = "[LOG] ";
$log = function($msg) use ($prefix) {
echo $prefix . $msg . "\n";
};
$log("System online");
?>
Closures capture values by value , not by reference (unless specified).
Binding Closures to Objects
PHP allows dynamically binding a closure to an object, modifying $this inside the closure.
Example:
<?php
class User {
public $name = "Alice";
}
$closure = function() {
return $this->name;
};
$obj = new User();
$bound = $closure->bindTo($obj, User::class);
echo $bound(); // Alice
?>
This allows injecting behavior into objects dynamically.
Generators (yield)
A generator is a special function that produces values lazily.
Example:
<?php
function countTo($limit) {
for ($i = 1; $i <= $limit; $i++) {
yield $i;
}
}
foreach (countTo(5) as $n) {
echo $n . " ";
}
?>
Benefits:
does not build arrays in memory,
efficient for large datasets,
supports send() and return (PHP 7+).
Returning a value from a generator:
<?php
function gen() {
yield 1;
return "done";
}
$g = gen();
foreach ($g as $v) {}
echo $g->getReturn(); // done
?>
Anonymous Recursion
A closure cannot refer to itself by name, so anonymous recursion uses use with references.
<?php
$fact = function($n) use (&$fact) {
return $n == 0 ? 1 : $n * $fact($n - 1);
};
echo $fact(5); // 120
?>
This technique is used in functional programming.
Currying and Partial Application
Currying transforms a function into a sequence of single-argument functions.
<?php
function currySum($a): callable {
return fn($b) => fn($c) => $a + $b + $c;
}
echo currySum(1)(2)(3); // 6
?>
Partial application: pre-filling some parameters.
<?php
function add($a, $b) { return $a + $b; }
$add5 = fn($x) => add(5, $x);
echo $add5(10); // 15
?>
Callable Types and Callbacks
A callable can be:
a string containing a function name,
a closure,
[object, "method"]
[ClassName::class, "method"]
a static method string ("Class::method")
Example with call_user_func:
<?php
function greet($name) { return "Hello, $name"; }
echo call_user_func("greet", "Alice");
?>
Array callable:
<?php
class A {
public function hello() { echo "Hi"; }
}
$a = new A();
call_user_func([$a, "hello"]);
?>
Check callability:
<?php
if (is_callable($fn)) {
$fn();
}
?>
Reflection API for Functions
PHP provides the Reflection API to examine functions at runtime.
Example:
<?php
function sample($a, $b) {}
$ref = new ReflectionFunction("sample");
print_r($ref->getParameters());
?>
Reflection can:
inspect parameters,
read default values,
get return type,
invoke functions dynamically,
modify behavior via reflection objects.
Generators with Keys and yield =>
You can control keys produced by generators:
<?php
function squares($n) {
for ($i = 1; $i <= $n; $i++) {
yield $i => $i * $i;
}
}
foreach (squares(3) as $k => $v) {
echo "$k => $v\n";
}
?>
This allows lazy associative data structures.
Function Factories
Functions that create and return functions.
<?php
function makeGreeter($greeting): callable {
return fn($name) => "$greeting, $name!";
}
$hi = makeGreeter("Hi");
echo $hi("Alice"); // Hi, Alice!
?>
Useful for creating reusable behaviors dynamically.
Decorators / Function Wrappers
You can wrap a function to extend its behavior — similar to decorators in Python.
<?php
function timed(callable $fn): callable {
return function(...$args) use ($fn) {
$start = microtime(true);
$result = $fn(...$args);
$end = microtime(true);
echo "Took " . ($end - $start) . "s\n";
return $result;
};
}
$slow = timed(function() {
sleep(1);
return "done";
});
echo $slow(); // prints time
?>
This pattern is common in logging, caching, and profiling.
Strict Types and Advanced Typing (PHP 7+)
Enable strict types at the top of the file:
<?php
declare(strict_types=1);
?>
This enforces exact type matches instead of automatic coercion.
Advanced return types:
void
never
union types (int|string)
intersection types
mixed
PHP Arrays
What Is an Array in PHP?
A PHP array is an ordered map — a flexible data structure storing key ⇒ value pairs.
Keys can be:
Values can be:
any data type (scalar, array, object, resource)
nested arbitrarily deep
Arrays can behave as:
lists
hashmaps
sets
stacks
queues
Creating Arrays
Short syntax (recommended):
<?php
$colors = ["red", "green", "blue"];
?>
Long syntax:
<?php
$colors = array("red", "green", "blue");
?>
Associative array:
<?php
$user = [
"name" => "Alice",
"age" => 25,
];
?>
Mixed numeric and string keys:
<?php
$mixed = [
0 => "a",
"key" => "b",
10 => "c",
];
?>
Array Keys and Automatic Indexing
Keys are auto-incremented starting from 0.
<?php
$a = [];
$a[] = "first"; // index 0
$a[] = "second"; // index 1
$a[] = "third"; // index 2
?>
Manual key assignment:
<?php
$a[10] = "x"; // index starts at 10
$a[] = "y"; // this becomes index 11
?>
String keys override integers if using numeric strings:
"1" is converted to 1
"01" stays a string key
Accessing Array Elements
<?php
echo $colors[1]; // green
?>
Access by string key:
<?php
echo $user["name"];
?>
Checking if a key exists:
isset() → checks existence & non-null
array_key_exists() → checks only existence
<?php
isset($user["age"]); // true
array_key_exists("age", $user); // true
?>
Modifying Arrays
<?php
$user["country"] = "Germany";
$user[] = "extra value";
?>
Update elements:
<?php
$user["age"] = 30;
?>
Remove elements:
<?php
unset($user["age"]);
?>
Clearing an array:
<?php
$user = [];
?>
Iterating Arrays
<?php
foreach ($colors as $c) {
echo $c;
}
?>
Iterating with keys:
<?php
foreach ($user as $key => $value) {
echo "$key = $value\n";
}
?>
By reference (to modify values):
<?php
foreach ($numbers as &$n) {
$n *= 2;
}
unset($n); // important!
?>
Multidimensional Arrays
Nested arrays represent matrices, tables, and structured data.
<?php
$matrix = [
[1, 2, 3],
[4, 5, 6],
];
echo $matrix[1][2]; // 6
?>
Associative nesting:
<?php
$person = [
"name" => "Alice",
"address" => [
"city" => "Berlin",
"zip" => 12345,
],
];
?>
Array Functions (Most Common)
<?php
count($colors);
?>
Push / pop:
<?php
array_push($colors, "yellow");
array_pop($colors); // removes last
?>
Shift / unshift:
<?php
array_unshift($colors, "pink");
array_shift($colors); // removes first
?>
Merge arrays:
<?php
$merged = array_merge($a, $b);
?>
Search in array:
<?php
in_array("blue", $colors);
array_search("green", $colors);
?>
Keys and values:
<?php
array_keys($user);
array_values($user);
?>
Filter / map / reduce:
<?php
$evens = array_filter($nums, fn($n) => $n % 2 == 0);
$doubled = array_map(fn($n) => $n * 2, $nums);
$sum = array_reduce($nums, fn($c,$n) => $c+$n, 0);
?>
Array Spread Operator (PHP 7.4+)
You can "unpack" arrays using ....
Example:
<?php
$a = [1, 2, 3];
$b = [...$a, 4, 5];
?>
Works with associative arrays (PHP 8.1+):
<?php
$a = ["x" => 1];
$b = ["y" => 2];
$c = [...$a, ...$b];
// ["x" => 1, "y" => 2]
?>
Sorting Arrays
<?php
sort($nums);
rsort($nums);
?>
Sort associative arrays by value:
<?php
asort($user);
arsort($user);
?>
Sort by key:
<?php
ksort($user);
krsort($user);
?>
Custom sort with comparator:
<?php
usort($nums, fn($a,$b) => $a <=> $b);
?>
Array Destructuring (PHP 7.1+)
You can “unpack” arrays into variables.
List syntax:
<?php
list($a, $b) = [10, 20];
?>
Short syntax:
<?php
[$x, $y] = [1, 2];
?>
Associative array destructuring:
<?php
["name" => $name, "age" => $age] = $user;
?>
PHP Advanced Array Operations
Array Mapping (array_map)
Apply a function to every element of an array.
<?php
$nums = [1, 2, 3];
$doubled = array_map(fn($n) => $n * 2, $nums);
// [2, 4, 6]
?>
Multiple arrays:
<?php
$a = [1,2,3];
$b = [4,5,6];
$sum = array_map(fn($x,$y) => $x + $y, $a, $b);
// [5, 7, 9]
?>
Preserves keys only if array_keys unchanged.
Filtering Arrays (array_filter)
Filter elements based on a predicate.
<?php
$nums = [1,2,3,4,5,6];
$evens = array_filter($nums, fn($n) => $n % 2 == 0);
// [2, 4, 6]
?>
Filter using values and keys:
<?php
$result = array_filter(
$user,
fn($v, $k) => $k === "age",
ARRAY_FILTER_USE_BOTH
);
?>
To reindex array: array_values().
Reducing Arrays (array_reduce)
Reduces array to a single value (sum, product, join).
<?php
$nums = [1,2,3,4];
$sum = array_reduce($nums, fn($c,$n) => $c + $n, 0);
// 10
?>
Build complex structures:
<?php
$result = array_reduce($words, fn($acc,$w) => $acc . strtoupper($w), "");
?>
Array Merging and Combining
<?php
$result = array_merge($a, $b);
?>
Spread/unpack operator (PHP 7.4+):
<?php
$merged = [...$a, ...$b, 100];
?>
Combine two arrays into associative form:
<?php
$keys = ["name","age"];
$values = ["Alice",25];
$assoc = array_combine($keys, $values);
// ["name" => "Alice", "age" => 25]
?>
Merge recursively:
<?php
array_merge_recursive($a, $b);
?>
Array Slicing (array_slice)
Extracts part of an array.
<?php
$part = array_slice($nums, 2, 3);
// from index 2, take 3 values
?>
Preserve keys:
<?php
array_slice($nums, 2, 3, true);
?>
Negative indexes allowed.
Array Splicing (array_splice)
Remove and optionally replace part of an array.
<?php
$nums = [1,2,3,4,5];
array_splice($nums, 1, 2, ["a","b"]);
// result: [1, "a", "b", 4, 5]
?>
Can be used to insert anywhere.
Advanced Searching
<?php
$key = array_search("blue", $colors);
?>
Strict search:
<?php
$key = array_search(0, ["0", 0, false], true);
// finds second element only
?>
Find all keys matching a condition:
<?php
$keys = array_keys($nums, 10);
?>
Set Operations
<?php
$unique = array_unique([1,2,2,3]);
// [1,2,3]
?>
Difference: values in A not in B
<?php
$diff = array_diff([1,2,3],[2]);
// [1,3]
?>
Intersection: common values
<?php
$inter = array_intersect([1,2,3],[2,3,4]);
// [2,3]
?>
Difference by keys:
<?php
array_diff_key($a, $b);
?>
User-defined comparison:
<?php
array_udiff($a, $b, fn($x,$y) => $x <=> $y);
?>
Chunking and Splitting Arrays
<?php
$chunks = array_chunk([1,2,3,4,5,6], 2);
// [[1,2],[3,4],[5,6]]
?>
Split into keys and values:
<?php
$keys = array_keys($user);
$values = array_values($user);
?>
Array Destructuring (Advanced)
<?php
["name" => $n, "age" => $a] = $user;
?>
Skip elements:
<?php
[$first,, $third] = [10,20,30];
?>
Array Pointers
PHP maintains an internal pointer for arrays.
Useful pointer functions:
current()
next()
prev()
reset()
end()
Example:
<?php
$colors = ["red","green","blue"];
echo current($colors); // red
next($colors);
echo current($colors); // green
end($colors); // blue
?>
Functional Programming with Arrays
Combining map → filter → reduce:
<?php
$sumOfSquares =
array_reduce(
array_map(fn($n) => $n * $n,
array_filter($nums, fn($n) => $n % 2 == 0)
),
fn($c,$v) => $c + $v,
0
);
?>
This creates expressive pipelines similar to Python or JavaScript.
Organizing PHP Files
Typical Small Project Structure
Simple structure for a small site:
project/
├── public/
│ ├── index.php
│ ├── about.php
│ ├── contact.php
│ └── assets/
│ ├── style.css
│ └── script.js
├── src/
│ ├── functions.php
│ ├── User.php
│ └── Mailer.php
├── config/
│ └── config.php
└── vendor/ (created by Composer)
Ideas:
public/ contains only web-accessible files (entry points, assets).
src/ contains application logic (classes, functions).
config/ holds configuration files.
vendor/ is managed by Composer.
The web server document root should be public/, not the project root.
Using a Front Controller (index.php)
Instead of many separate PHP files as entry points, use a single front controller:
Example basic front controller:
<?php
// public/index.php
require __DIR__ . "/../vendor/autoload.php";
require __DIR__ . "/../config/config.php";
$uri = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
if ($uri === "/" || $uri === "/index.php") {
require __DIR__ . "/../src/Controllers/HomeController.php";
(new HomeController())->index();
} elseif ($uri === "/contact") {
require __DIR__ . "/../src/Controllers/ContactController.php";
(new ContactController())->showForm();
} else {
http_response_code(404);
echo "Not Found";
}
?>
Advantages:
centralized routing,
uniform error handling,
easier middleware (auth, logging).
Separating Configuration Files
Keep configuration out of main scripts.
Example config/config.php:
<?php
return [
"db" => [
"host" => "localhost",
"name" => "app",
"user" => "root",
"pass" => "",
],
"debug" => true,
];
?>
Usage in front controller or bootstrap:
<?php
$config = require __DIR__ . "/../config/config.php";
$dbConfig = $config["db"];
?>
Benefits:
easier to change environment-specific values,
config can be excluded from version control if it contains secrets.
Using require, include, and autoload
For manual organization:
require / require_once → fatal error if missing.
include / include_once → warning if missing.
Example:
<?php
require __DIR__ . "/../src/functions.php";
require __DIR__ . "/../src/User.php";
?>
Better: use Composer’s autoloader:
<?php
require __DIR__ . "/../vendor/autoload.php";
// classes are loaded automatically by namespace
?>
Autoloading avoids many manual require calls and keeps files clean.
Organizing with Namespaces and PSR-4
Namespaces prevent name conflicts and map naturally to directories.
Example class with namespace:
<?php
// src/Service/Mailer.php
namespace App\Service;
class Mailer {
public function send(string $to, string $subject, string $body): void {
// ...
}
}
?>
composer.json for PSR-4 autoloading:
<?php
{
"autoload": {
"psr-4": {
"App\\\\" : "src/"
}
}
}
Then run:
composer dump-autoload
Usage in code:
<?php
use App\Service\Mailer;
$mailer = new Mailer();
?>
Separating Views (Templates) from Logic
Store HTML templates separately from PHP logic.
Example structure:
src/
├── Controllers/
│ └── HomeController.php
└── Views/
├── layout.php
└── home.php
Simple controller:
<?php
// src/Controllers/HomeController.php
namespace App\Controllers;
class HomeController {
public function index(): void {
$title = "Home";
$message = "Welcome!";
require __DIR__ . "/../Views/home.php";
}
}
?>
Simple view:
<?php /* src/Views/home.php */ ?>
<!doctype html>
<html>
<head>
<title><?= htmlspecialchars($title) ?></title>
</head>
<body>
<h1><?= htmlspecialchars($message) ?></h1>
</body>
</html>
Goal:
controllers prepare data,
views handle presentation,
no SQL or heavy logic inside view files.
Organizing Environment-Specific Settings
Avoid hardcoding secrets and environment-specific values in tracked files.
Use .env files loaded by a library (like vlucas/phpdotenv) or environment variables.
Example config loader:
<?php
// config/env.php
$env = [
"DB_HOST" => getenv("DB_HOST") ?: "localhost",
"DB_NAME" => getenv("DB_NAME") ?: "app",
];
?>
Keep .env out of version control and commit a .env.example instead.
Splitting Logic into Domains (Controllers, Services, Models)
As project grows, organize src/ by responsibility:
src/
├── Controllers/
├── Models/
├── Service/
├── Repository/
└── Helpers/
Examples:
Controllers : handle HTTP requests and responses.
Models : represent domain entities (User, Post, Order).
Services : business logic (Mailer, PaymentService).
Repositories : database access layer.
Helpers : generic functions (string utilities, array helpers).
Idea: put each concern in its own file and directory.
Organizing Reusable Functions and Helpers
Option 1: a simple functions.php (for small projects).
Option 2: split helpers by topic:
src/
├── Helpers/
│ ├── StringHelper.php
│ ├── ArrayHelper.php
│ └── HtmlHelper.php
Example static helper:
<?php
namespace App\Helpers;
class StringHelper {
public static function slugify(string $text): string {
$text = strtolower(trim($text));
$text = preg_replace("/[^a-z0-9]+/", "-", $text);
return trim($text, "-");
}
}
?>
Usage:
<?php
use App\Helpers\StringHelper;
$slug = StringHelper::slugify("Hello World!");
?>
Organizing Tests (If You Use PHPUnit)
Place tests in a separate tests/ directory.
project/
├── src/
└── tests/
├── UserTest.php
└── Service/
└── MailerTest.php
Match namespace structure between src/ and tests/ for clarity.
Organizing for Deployment
Only the necessary files should be deployed to the web server:
public/
src/
vendor/
config/ (without secrets in version control)
Exclude:
development tools,
local configuration files,
tests/,
documentation that is not needed at runtime.
Make sure the web server document root is public/, so src/ is not directly accessible via URL.
PHP State Management
What Is “State” in PHP and HTTP?
HTTP is a stateless protocol:
each request is independent,
the server does not automatically “remember” previous requests.
State management in PHP means:
remembering information across multiple requests,
linking requests to the same user (session),
storing things like login status, shopping cart, preferences.
Main tools in PHP for state management:
query parameters ($_GET)
form data ($_POST)
cookies ($_COOKIE)
sessions ($_SESSION)
server-side storage (database, cache, files)
URL routing (path-based “state”)
Per-Request Data: $_GET and $_POST
Request data is one-time state: it exists only for that HTTP request.
Query parameters ($_GET):
<?php
// URL: /search.php?q=php+state&page=2
$q = $_GET["q"] ?? "";
$page = (int)($_GET["page"] ?? 1);
?>
Form data ($_POST):
<?php
// After submitting a <form method="post">
$username = $_POST["username"] ?? "";
$password = $_POST["password"] ?? "";
?>
Characteristics:
exists only during the request,
good for single actions (login, submit form),
not persistent by itself (unless you store it somewhere).
Client-Side State: Cookies ($_COOKIE)
Cookies are small pieces of data stored in the browser and sent with each request to the same domain.
PHP reads them via $_COOKIE and sends them with setcookie().
Setting a cookie:
<?php
// Must be called before any output
setcookie(
"theme", // name
"dark", // value
time() + 3600, // expire (1 hour)
"/", // path
"", // domain (default)
true, // secure (HTTPS only)
true // HttpOnly (not accessible via JS)
);
?>
Reading a cookie:
<?php
$theme = $_COOKIE["theme"] ?? "light";
?>
Cookie properties:
Persistent across requests until expiration.
Stored and controlled by the client (user can delete or modify).
Size-limited and insecure for sensitive data (never store raw passwords, secrets).
Typical uses:
remembering language preference,
“remember me” tokens (hashed, secure),
UI theme, tracking IDs.
Server-Side State: Sessions ($_SESSION)
Sessions link multiple requests to the same user by:
issuing a session ID (usually in a cookie PHPSESSID),
storing session data on the server (file, memory, etc.),
reloading that data each time the session ID is sent.
Starting a session:
<?php
// At the top of script, before output
session_start();
?>
Storing state:
<?php
$_SESSION["user_id"] = 42;
$_SESSION["cart"] = ["product_1" => 2, "product_5" => 1];
?>
Reading state:
<?php
session_start();
$userId = $_SESSION["user_id"] ?? null;
$cart = $_SESSION["cart"] ?? [];
?>
Ending a session (logout):
<?php
session_start();
$_SESSION = [];
session_destroy();
?>
Sessions are the main tool for:
login state,
shopping carts,
wizards / multi-step forms,
user preferences during a visit.
State via URL: Path and Query Design
Part of state can be encoded in URLs:
path segments: /products/42 → product ID 42
query parameters: ?page=2&sort=price
Example simple router:
<?php
$uri = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
if (preg_match("~^/product/(\\d+)$~", $uri, $m)) {
$productId = (int)$m[1];
// load product from DB
}
?>
URL-based state:
is shareable (bookmarks, links),
ideal for read-only state (filters, sorting, pagination),
not suitable for secrets or sensitive actions by itself.
Persistent State: Database and Storage
For long-term or multi-device state, use a database or other storage:
SQL DB (MySQL, PostgreSQL)
NoSQL (Redis, Mongo)
files, key-value stores
Typical pattern:
Use sessions for short-lived UI state (who is logged in).
Use DB for persistent state (user profile, orders, messages).
Example: user preferences in DB + session cache:
<?php
session_start();
if (!isset($_SESSION["prefs"])) {
// query database once
$_SESSION["prefs"] = loadUserPrefsFromDb($_SESSION["user_id"]);
}
$prefs = $_SESSION["prefs"];
?>
Managing Authentication State
Common pattern:
user posts credentials via $_POST,
you verify against DB,
you store user ID in $_SESSION,
later requests check $_SESSION["user_id"] to know who is logged in.
Example login handling:
<?php
session_start();
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$user = findUserByEmail($_POST["email"]);
if ($user && password_verify($_POST["password"], $user["password_hash"])) {
$_SESSION["user_id"] = $user["id"];
header("Location: /dashboard.php");
exit;
} else {
$error = "Invalid credentials";
}
}
?>
Checking authentication on protected pages:
<?php
session_start();
if (!isset($_SESSION["user_id"])) {
header("Location: /login.php");
exit;
}
?>
Optional enhancement: remember-me cookies with secure tokens + DB.
Flash Messages (One-Time State)
Flash messages are short-lived messages that survive one redirect and then disappear:
“Profile updated successfully”
“Login failed”
Implement via session:
<?php
// Set flash
$_SESSION["flash"] = "Profile saved!";
header("Location: /profile.php");
exit;
Read and clear:
<?php
session_start();
$flash = $_SESSION["flash"] ?? null;
unset($_SESSION["flash"]);
?>
This pattern is very common in frameworks (Laravel, Symfony, etc.).
State Management in APIs (Stateless vs Session-Based)
For REST-ish APIs, it is common to keep them stateless :
authentication via tokens (JWT, API keys) in headers,
no PHP session usage,
each request is self-contained.
Example: token passed in header:
<?php
$headers = getallheaders();
$token = $headers["Authorization"] ?? null;
// validate token, load user from DB
?>
Sessions are still possible in APIs, but tokens are more scalable for mobile / external clients.
Security Considerations in State Management
Never store sensitive data in cookies (passwords, card info).
Use:
HttpOnly cookies to prevent JavaScript access,
Secure flag over HTTPS.
Regenerate session IDs on login to prevent fixation:
<?php
session_start();
session_regenerate_id(true);
?>
Protect against CSRF when using cookies for authentication:
use CSRF tokens in forms,
or use SameSite cookies.
Validate and sanitize any state coming from the client (cookies, GET, POST).
Overview of Form Processing in PHP
Forms are the main way users send data to a PHP backend.
Data from forms is sent via:
method="get" → appears in URL as query parameters
method="post" → sent in HTTP request body
PHP retrieves this data using:
$_GET
$_POST
$_FILES (for upload)
$_REQUEST (not recommended; mixes all)
A full form workflow:
user loads form,
submits form to PHP script,
PHP validates input,
PHP takes action (save DB, send email, update file),
optional redirect + flash message.
Creating a Basic Form
<form action="process.php" method="post">
<label>Name:</label>
<input type="text" name="name">
<label>Email:</label>
<input type="email" name="email">
<button type="submit">Submit</button>
</form>
action → PHP file that handles the data.
method :
POST for sensitive or large data.
GET for simple search/filter queries.
Accessing Form Data in PHP
<?php
$name = $_POST["name"] ?? "";
$email = $_POST["email"] ?? "";
?>
PHP variables are populated automatically based on input name attributes.
For GET requests:
<?php
$query = $_GET["q"] ?? "";
?>
Always check for missing values using ?? to avoid errors.
Detecting Form Submission
Check the request method:
<?php
if ($_SERVER["REQUEST_METHOD"] === "POST") {
// form submitted
}
?>
Alternatively check a specific field:
<?php
if (isset($_POST["name"])) {
// name field submitted
}
?>
Validating Form Inputs
Example validation steps:
<?php
$errors = [];
if (empty($name)) {
$errors[] = "Name is required.";
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Invalid email address.";
}
?>
Common validations:
required field
email format
min/max length
numeric / integer validation
regex validation
Built-in validators:
FILTER_VALIDATE_EMAIL
FILTER_VALIDATE_INT
FILTER_SANITIZE_STRING (deprecated)
Sanitizing and Escaping Input
Sanitization → cleaning input.
Escaping → preventing HTML output attacks (XSS).
Escape output with htmlspecialchars():
<?php
$safeName = htmlspecialchars($name);
?>
Preventing XSS:
always escape data when printing to HTML,
validate the input strictly.
Sanitize email:
<?php
$email = filter_var($email, FILTER_SANITIZE_EMAIL);
?>
Displaying Validation Errors
Example error display block:
<?php if (!empty($errors)): ?>
<ul style="color:red;">
<?php foreach ($errors as $e): ?>
<li><?= htmlspecialchars($e) ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
Best practice: redisplay the form with errors filled in.
Preserving Form Values After Submission
Use value="<?= htmlspecialchars($name) ?>" inside the form:
<input type="text" name="name" value="<?= htmlspecialchars($name) ?>">
Checkbox example:
<input type="checkbox" name="subscribe"
<?php if (!empty($_POST["subscribe"])) echo "checked"; ?> >
Important for:
multi-step forms,
login failure pages,
complex form submissions.
Processing Checkbox, Radio, and Select Fields
<?php
$subscribe = isset($_POST["subscribe"]);
?>
Radio:
<?php
$gender = $_POST["gender"] ?? "";
?>
Select:
<?php
$country = $_POST["country"] ?? "";
?>
Multi-select: (note the [] in name)
<?php
$colors = $_POST["colors"] ?? []; // array
?>
Redirect After Processing (Post/Redirect/Get)
After processing form logic, redirect to avoid duplicate submissions.
Pattern: POST → Redirect → GET
Example:
<?php
// process.php
session_start();
$_SESSION["flash"] = "Form submitted!";
header("Location: success.php");
exit;
?>
Then on success.php:
<?php
session_start();
$flash = $_SESSION["flash"] ?? "";
unset($_SESSION["flash"]);
?>
Handling File Uploads
<form method="post" enctype="multipart/form-data">
Processing upload:
<?php
$file = $_FILES["upload"];
if ($file["error"] === UPLOAD_ERR_OK) {
move_uploaded_file($file["tmp_name"], "uploads/" . $file["name"]);
}
?>
Validate:
file size ($_FILES["upload"]["size"])
mime type
extensions
upload errors
Never trust uploaded filenames → sanitize or generate unique names.
Security Considerations
Always escape output with htmlspecialchars().
Validate all user input rigorously.
Use CSRF tokens to protect against cross-site request forgery.
Limit file upload types and sizes.
Never trust $_REQUEST—use $_GET and $_POST explicitly.
Use HTTPS to avoid leaking form data.
PHP Working with Files
Checking File Existence and Metadata
<?php
if (file_exists("data.txt")) {
echo "File exists";
}
?>
Other useful checks:
<?php
is_file("a.txt"); // true if it is a regular file
is_dir("uploads"); // true if directory
filesize("data.txt"); // file size in bytes
filemtime("data.txt"); // last modification time
?>
Listing files in a directory:
<?php
$files = scandir("uploads");
// [".", "..", "a.jpg", "b.png", ...]
?>
Reading Files
Read entire file as a string:
<?php
$content = file_get_contents("data.txt");
?>
Read a file line by line:
<?php
$lines = file("data.txt");
foreach ($lines as $line) {
echo $line;
}
?>
Reading with a file handle:
<?php
$fp = fopen("data.txt", "r");
while ($line = fgets($fp)) {
echo $line;
}
fclose($fp);
?>
Use file handles for large files to avoid memory overload.
Writing Files
Write entire content (overwrites existing file):
<?php
file_put_contents("output.txt", "Hello World!");
?>
Append to file:
<?php
file_put_contents("log.txt", "New entry\n", FILE_APPEND);
?>
Write using manual file handle:
<?php
$fp = fopen("data.txt", "w"); // or "a" for append
fwrite($fp, "Some content");
fclose($fp);
?>
Writing modes:
"w" → write (truncate)
"a" → append
"x" → create new file, fail if exists
"r+" → read/write without truncating
Working with Directories
<?php
mkdir("uploads");
?>
Create with nested directories:
<?php
mkdir("a/b/c", recursive: true);
?>
Remove directory: (must be empty)
<?php
rmdir("uploads");
?>
Remove file:
<?php
unlink("old.txt");
?>
File Uploads via Forms
<form method="post" enctype="multipart/form-data">
<input type="file" name="upload">
<button type="submit">Upload</button>
</form>
PHP processing:
<?php
$file = $_FILES["upload"];
if ($file["error"] === UPLOAD_ERR_OK) {
$tmp = $file["tmp_name"];
$name = basename($file["name"]);
move_uploaded_file($tmp, "uploads/" . $name);
}
?>
This ensures uploaded files are stored securely in a real location.
Handling File Upload Errors
<?php
switch ($file["error"]) {
case UPLOAD_ERR_OK:
echo "Success";
break;
case UPLOAD_ERR_NO_FILE:
echo "No file uploaded";
break;
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
echo "File too large";
break;
default:
echo "Unknown error";
}
?>
Always validate:
file size
file extension
MIME type
Reading and Writing CSV Files
<?php
$fp = fopen("data.csv", "r");
while ($row = fgetcsv($fp)) {
print_r($row);
}
fclose($fp);
?>
Writing CSV:
<?php
$fp = fopen("output.csv", "w");
fputcsv($fp, ["id", "name", "email"]);
fputcsv($fp, [1, "Alice", "alice@mail.com"]);
fclose($fp);
?>
Working with JSON Files
<?php
$data = json_decode(file_get_contents("data.json"), true);
?>
Writing JSON:
<?php
file_put_contents("out.json", json_encode($data, JSON_PRETTY_PRINT));
?>
JSON is ideal for structured data exchange.
File Locking for Concurrency
Use locks to avoid race conditions:
<?php
$fp = fopen("log.txt", "a");
if (flock($fp, LOCK_EX)) {
fwrite($fp, "hello\n");
flock($fp, LOCK_UN);
}
fclose($fp);
?>
Useful when multiple users may write to the same file.
File Downloads
Force file download in browser:
<?php
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"report.txt\"");
readfile("report.txt");
exit;
?>
Common in export features (PDF, CSV, backup).
Security Considerations
PHP Date and Time
Overview of Date and Time Handling in PHP
PHP provides rich built-in tools to work with:
current time
formatting dates
parsing date strings
timezones
date arithmetic
timestamps
Core components:
date() — format timestamps
time() — current Unix timestamp
DateTime — object-based date/time API
DateTimeZone
DateInterval
strtotime() — parse date strings
The recommended modern API is DateTime , not raw date().
Getting the Current Date and Time
<?php
$now = time(); // e.g. 1732280000
?>
Formatted current date:
<?php
echo date("Y-m-d H:i:s");
?>
Common format characters:
Y = 4-digit year
m = month (01-12)
d = day
H = hour (24h)
i = minute
s = second
DateTime Class (Recommended)
Create a new DateTime instance:
<?php
$dt = new DateTime();
echo $dt->format("Y-m-d H:i:s");
?>
Create from a specific date string:
<?php
$dt = new DateTime("2024-10-31 12:30");
?>
Create from a timestamp:
<?php
$dt = new DateTime("@1732280000");
?>
Format using format():
<?php
echo $dt->format("l, d M Y H:i");
?>
Advantages:
mutable or immutable variants
timezone support
safe parsing
easy arithmetic
Timezones
<?php
echo date_default_timezone_get();
?>
Set timezone globally:
<?php
date_default_timezone_set("Europe/Berlin");
?>
Create DateTime with specific timezone:
<?php
$tz = new DateTimeZone("Asia/Shanghai");
$dt = new DateTime("now", $tz);
?>
Convert timezone:
<?php
$dt->setTimezone(new DateTimeZone("America/New_York"));
?>
Date Arithmetic (Adding / Subtracting Time)
Add or subtract intervals:
<?php
$dt = new DateTime("2024-01-01");
$dt->modify("+10 days");
$dt->modify("-2 months");
?>
DateInterval:
<?php
$dt = new DateTime();
$dt->add(new DateInterval("P1Y2M10D")); // +1 year, 2 months, 10 days
?>
Interval format:
P = period
T = time
Example: P3DT4H = 3 days, 4 hours
Calculating Date Differences
<?php
$start = new DateTime("2024-01-01");
$end = new DateTime("2024-12-31");
$diff = $start->diff($end);
echo $diff->days; // total number of days
echo $diff->format("%m months, %d days");
?>
Useful for:
age calculations
countdown timers
billing periods
subscriptions
Parsing Dates from Strings (strtotime())
strtotime() converts natural language to a timestamp.
Examples:
<?php
echo strtotime("now");
echo strtotime("tomorrow");
echo strtotime("next Monday");
echo strtotime("2024-10-31 12:00");
?>
Common with date():
<?php
echo date("Y-m-d", strtotime("next month"));
?>
Working with Unix Timestamps
<?php
echo time();
?>
Create a timestamp for a specific date:
<?php
$ts = mktime(12, 0, 0, 10, 31, 2024);
?>
Convert timestamp to formatted date:
<?php
echo date("Y-m-d H:i:s", 1732280000);
?>
Date Formatting Examples
<?php
echo date("Y-m-d"); // 2024-10-31
echo date("d/m/Y"); // 31/10/2024
echo date("l"); // Thursday
echo date("H:i:s"); // 17:30:45
echo date("r"); // RFC 2822 format
echo date(DATE_ATOM); // ISO 8601
?>
International formats:
ISO-8601: Y-m-d\TH:i:sP
Database (SQL): Y-m-d H:i:s
Immutable Dates (DateTimeImmutable)
Immutable variant of DateTime:
<?php
$dt = new DateTimeImmutable("2024-01-01");
$new = $dt->modify("+1 day"); // returns new object
?>
Useful when:
you want safe operations,
avoid accidental mutations,
functional style programming.
Working with Time Intervals
<?php
$interval = new DateInterval("PT30M"); // 30 minutes
?>
Use with DateTime:
<?php
$dt = new DateTime();
$dt->add(new DateInterval("P7D")); // +7 days
?>
Subtract interval:
<?php
$dt->sub(new DateInterval("P1M")); // -1 month
?>
Generating Timestamps for Logging
<?php
$logTime = (new DateTime())->format("Y-m-d H:i:s");
?>
Common in:
error logs
user activity logs
audit trails
PHP Namespaces
What Are Namespaces in PHP?
A namespace is a virtual container that groups related classes, functions, and constants together.
The main purpose is to avoid naming conflicts between different parts of a program or between different libraries.
When you use namespaces:
class names become organized
you avoid clashes between similar class names
autoloading becomes easier (PSR-4)
project structure becomes clearer
Namespaces in PHP are similar to:
Java packages
C# namespaces
Python modules
Declaring a Namespace
Declare a namespace at the top of a PHP file:
<?php
namespace App\Controllers;
class HomeController {
public function index() {
echo "Home";
}
}
?>
The namespace must be the first PHP statement in the file.
Namespace naming rules:
use \ to create nested namespaces
use PascalCase for namespaces (recommended)
match directory structure when using autoloaders
Using Namespaced Classes
When accessing a class in a namespace, you must specify its full path:
<?php
$user = new App\Models\User();
?>
Or import it with use:
<?php
use App\Models\User;
$user = new User();
?>
This makes code shorter and cleaner.
Namespace Aliases
You can rename (alias) namespaces with as:
<?php
use App\Models\User as UserModel;
$user = new UserModel();
?>
Useful when two namespaces have classes with the same name.
Grouping Multiple Imports
You can group imports from the same namespace:
<?php
use App\Models\{User, Product, Order};
$user = new User();
?>
This reduces long lists of use statements.
Global Namespace
The global namespace contains PHP built-in classes and any file without a namespace.
To access a global class inside a namespaced file, prefix with \:
<?php
namespace App\Utils;
$dt = new \DateTime(); // global class
?>
Without \, PHP would look for App\Utils\DateTime.
Defining Functions and Constants in Namespaces
You can define functions in a namespace:
<?php
namespace App\Helpers;
function greet($name) {
return "Hello, $name";
}
?>
And constants:
<?php
namespace App\Config;
const APP_VERSION = "1.0.0";
?>
To access them:
<?php
use function App\Helpers\greet;
use const App\Config\APP_VERSION;
echo greet("Alice");
echo APP_VERSION;
?>
Subnamespaces and Project Organization
Namespaces reflect directory structure in modern PHP projects.
Example typical structure:
src/
├── Controllers/
│ ├── HomeController.php
│ └── UserController.php
├── Models/
│ ├── User.php
│ └── Product.php
└── Services/
├── Mailer.php
└── AuthService.php
Corresponding namespaces:
<?php
namespace App\\Controllers;
namespace App\\Models;
namespace App\\Services;
?>
How Namespaces Work with Autoloading (PSR-4)
Namespaces map to folders via Composer autoload .
composer.json example:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
This means:
App\Controllers\HomeController → src/Controllers/HomeController.php
App\Models\User → src/Models/User.php
Then run:
composer dump-autoload
Autoloading allows you to avoid writing require or include everywhere.
Nested Namespaces in One File
You can declare multiple namespaces in one file, but it's uncommon:
<?php
namespace App\First {
class A {}
}
namespace App\Second {
class B {}
}
?>
Better practice: one class = one file.
Fully Qualified Names vs Relative Names
Fully qualified name (absolute):
\App\Models\User
Qualified name (relative):
Models\User
Unqualified name:
User
PHP resolves names using:
current namespace
use imports
global namespace (with \)
Common Errors and Pitfalls
<?php
// wrong inside a namespace
new DateTime();
// correct
new \DateTime();
?>
Too many classes in one namespace — break into subnamespaces.
Using long use lists — group them or alias them.