PHP runs on the server, before the page reaches your visitor. It is how a website asks
"who is signed in?", saves a form, checks a password or pulls rows from a database. It still powers most of
the web, including WordPress.
PHP was created by Rasmus Lerdorf in 1994 and now stands for PHP: Hypertext Preprocessor. Your
file normally ends in .php and lives on a web server. The server runs the PHP, then sends
plain HTML to the browser. View source in the browser and you will see the result โ never the PHP.
Setting up
1
Install XAMPP (Windows/Mac/Linux) โ it gives you PHP, Apache and MySQL in one package.
2
Put your files in the htdocs folder and open http://localhost/yourfile.php.
3
Or skip Apache entirely: php -S localhost:8000 in your project folder is enough to start learning.
4
VS Code + the PHP extension gives you highlighting, error checking and a debugger.
PHPhello.php
<?php
// comments: // or # or /* ... */
echo "Hello, Study Hub!"; // print text
echo 2 + 3; // 5
print "Hi there"; // print works too
// everything outside <?php ... ?> is sent as plain HTML
?>
<h1>This heading is normal HTML</h1>
<p>The PHP above ran on the server.</p>
02
Variables & data types
Every variable starts with a dollar sign
$name"Ayush"string
$marks87integer
$percent87.5float
$passedtrueboolean
PHPtypes.php
<?php
$name = "Ayush"; // string - always in quotes
$marks = 87; // integer
$percent = 87.5; // float
$passed = true; // boolean
$empty = null; // nothing yet
var_dump($marks); // int(87) - shows type AND value
// double quotes read variables, single quotes do not
echo "Hi $name"; // Hi Ayush
echo 'Hi $name'; // Hi $name
// joining text uses a dot, not a plus
echo "Scored: " . $marks . "/100";
// converting types
$age = (int) "15"; // 15
$str = (string) 99; // "99"
$n = intval("42"); // 42
// constants never change
define("SITE_NAME", "Study Hub");
const GST = 0.18;
echo SITE_NAME . " GST: " . GST;
1
PHP is loosely typed โ $x = "5"; $x = 10; is legal. It is convenient, but it also means you must be careful.
2
Variables are case-sensitive ($Name and $name differ) but function names and keywords are not.
3
Concatenation uses . โ write $a . " " . $b. A + between two strings will try to do maths instead.
03
Operators & text handling
Maths, comparisons and the string functions you will actually use
Curly braces, colons and the same logic as every language
PHPdecisions.php
<?php
$marks = 78;
if ($marks >= 90) {
$grade = "A+";
} elseif ($marks >= 75) {
$grade = "A";
} elseif ($marks >= 33) {
$grade = "B";
} else {
$grade = "F";
}
echo $grade; // A
// ternary
$label = $marks >= 33 ? "Pass" : "Fail";
// switch - compares loosely, so use === checks when it matters
switch (true) {
case $marks >= 90: $tag = "Outstanding"; break;
case $marks >= 33: $tag = "Passed"; break;
default: $tag = "Failed";
}
// match (PHP 8) is stricter and shorter
$colour = match (true) {
$marks >= 90 => "gold",
$marks >= 33 => "green",
default => "red",
};
PHPloops.php
<?php
// for - you know the count
for ($i = 1; $i <= 5; $i++) {
echo $i . " ";
}
// while
$count = 1;
while ($count <= 3) {
echo "Round $count";
$count++; // forget this and it never ends
}
// foreach - by far the most used loop in PHP
$subjects = ["Maths", "Science", "English"];
foreach ($subjects as $subject) {
echo "I study $subject";
}
// foreach with the key
$marksMap = ["Maths" => 78, "Science" => 91];
foreach ($marksMap as $subject => $score) {
echo "$subject: $score";
}
// break and continue
foreach ($subjects as $s) {
if ($s === "Science") continue; // skip this one
echo $s;
}
The foreach ($items as $item): … endforeach; style is preferred when mixing loops with HTML, because it keeps the tags readable.
2
<?= $value ?> is a shortcut for <?php echo $value; ?>.
3
A while loop whose condition never turns false will hang the request until the server times out. Refresh and check the condition.
05
Arrays
PHP's superpower โ ordered lists and labelled records in one type
PHParrays.php
<?php
// indexed array
$marks = [78, 91, 66];
$marks[] = 88; // add to the end
echo $marks[0]; // 78
echo count($marks); // 4
// associative array - named keys (this is what comes back from a database)
$student = [
"name" => "Ayush",
"marks" => ["Maths" => 78, "Science" => 91],
"city" => "Shimla",
];
echo $student["name"]; // Ayush
echo $student["marks"]["Science"]; // 91
$student["phone"] = "99999-00000"; // add a key
echo $student["phone"] ?? "none"; // safe read
// useful functions
sort($marks); // sorts in place, lowest first
rsort($marks); // highest first
$unique = array_unique([1, 1, 2, 3]); // remove duplicates
$total = array_sum([78, 91, 66]); // 235
$avg = array_sum($marks) / count($marks);
print_r($marks); // readable dump while debugging
var_dump($student); // full dump with types
// array of arrays - the shape of every database result
$classMarks = [
["name" => "Ayush", "marks" => [78, 91, 66]],
["name" => "Riya", "marks" => [92, 88, 95]],
];
foreach ($classMarks as $s) {
$avg = array_sum($s["marks"]) / count($s["marks"]);
printf("%-6s %6.1f\n", $s["name"], $avg);
}
// --- the functions you will use all the time ---
$nums = [1, 2, 3, 4, 5];
$doubled = array_map(fn($n) => $n * 2, $nums);
$evens = array_filter($nums, fn($n) => $n % 2 === 0);
$sum = array_reduce($nums, fn($a, $b) => $a + $b, 0);
print_r($doubled); // [2,4,6,8,10]
echo $sum; // 15
// is it in the array?
var_dump(in_array("Science", ["Maths", "Science"])); // true
print_r(array_keys($student));
06
Functions
Reusable blocks, arrow functions and includes
PHPfunctions.php
<?php
function greet(string $name): string {
return "Hello, $name!";
}
echo greet("Ayush");
// default and typed parameters
function power(int $base, int $exponent = 2): int {
return $base ** $exponent;
}
echo power(5); // 25
echo power(2, 10); // 1024
// arrow function - short one-liners
$double = fn($n) => $n * 2;
echo $double(7); // 14
// closure that remembers a value from outside
$rate = 0.18;
$withGst = function ($amount) use ($rate) {
return $amount + $amount * $rate;
};
echo $withGst(1000); // 1180
// functions can return an array when you need several values
function stats(array $nums): array {
return [
"count" => count($nums),
"total" => array_sum($nums),
"avg" => array_sum($nums) / max(count($nums), 1),
];
}
$s = stats([78, 91, 66]);
echo "Average: " . round($s["avg"], 1);
Splitting code across files
PHPpage.php
<?php
require_once "header.php"; // crashes if missing (use this)
// include "header.php"; // only warns if missing
echo "Page content here";
require __DIR__ . "/footer.php"; // __DIR__ keeps paths reliable
1
Type hints (string $name, : int) are optional but they catch real mistakes early โ use them.
2
Put shared code (database connection, helpers) in its own file and pull it in with require_once.
3
Use __DIR__ . "/file.php" instead of a bare filename โ the current folder can change between requests.
07
Forms & the server
Where PHP actually earns its place
A form sends data to your PHP file. method="get" puts it in the URL (good for searching),
method="post" sends it hidden in the request body (required for passwords and anything
that changes data).
<?php
// Only run when the form was actually submitted
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
http_response_code(405);
exit("Method not allowed");
}
// Read, trim, then validate. Use ?? so missing keys never crash.
$student = trim($_POST["student"] ?? "");
$marks = $_POST["marks"] ?? "";
$note = trim($_POST["note"] ?? "");
$errors = [];
if ($student === "") {
$errors[] = "Student name is required.";
}
if (!is_numeric($marks) || $marks < 0 || $marks > 100) {
$errors[] = "Marks must be a number between 0 and 100.";
}
if ($errors) {
foreach ($errors as $e) {
echo "<p class=\"error\">" . htmlspecialchars($e) . "</p>";
}
exit;
}
// Safe to use now - and always escape when printing back to HTML
echo "Saved " . htmlspecialchars($student) . " with " . (int) $marks . " marks.";
?>
The superglobals you need to know
Variable
Holds
Typical use
$_GET
Values from the URL query string
Search terms, page numbers
$_POST
Values submitted by a form
Logins, saving data
$_SESSION
Data remembered across pages
Keeping a user signed in
$_COOKIE
Values stored in the browser
Remember-me, theme choice
$_SERVER
Request and server details
REQUEST_METHOD, IP, URL
$_FILES
Uploaded files
Profile pictures, documents
PHPlogin.php
<?php
session_start();
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$user = trim($_POST["user"] ?? "");
$pass = $_POST["pass"] ?? "";
// In a real app: fetch the row from the database, then use
// password_verify($pass, $row["password_hash"]).
// Never compare plain-text passwords.
if ($user !== "" && $pass !== "") {
$_SESSION["user"] = $user; // signed in
header("Location: dashboard.php"); // redirect
exit;
}
$error = "Enter both fields.";
}
// On another page, check the session
// if (!isset($_SESSION["user"])) { header("Location: login.php"); exit; }
1
Never trust a form. Validate every field on the server, even if you already checked it in JavaScript.
2
Escape everything you print back with htmlspecialchars(), and never build SQL by pasting values into a string.
3
Call header("Location: ...") before any HTML output, then exit so nothing else runs.
4
Passwords are stored with password_hash() and checked with password_verify() โ never as plain text.
08
Errors & staying safe
PHP tells you exactly what went wrong โ learn to read it
Outputa typical PHP error
Warning: Undefined array key "name" in C:\xampp\htdocs\app.php on line 12
Parse error: syntax error, unexpected '}' in app.php on line 27
Fatal error: Uncaught TypeError: greet(): Argument #1 ($name)
must be of type string, int given in app.php:5
Six errors you will hit this week
1
Parse error โ a missing semicolon, bracket or quote. The program does not run at all.
2
Undefined variable / array key โ you read something that is not set. Guard it with ?? "" or isset().
3
Headers already sent โ you printed HTML before calling header() or session_start(). Move them to the very top.
4
Fatal error: Call to undefined function โ a typo, or the extension (like mysqli) is not enabled in php.ini.
5
TypeError โ a type hint did not match. Convert the value before passing it.
6
Blank white page โ a fatal error with display off. Check the server error log, or switch on display_errors while developing.
PHPsafe.php
<?php
// --- see errors while developing, hide them in production ---
ini_set("display_errors", "1");
error_reporting(E_ALL);
// --- validate instead of hoping ---
function toMarks($raw): ?int {
if (!is_numeric($raw)) return null;
$n = (int) $raw;
return ($n < 0 || $n > 100) ? null : $n;
}
$marks = toMarks($_GET["m"] ?? null);
echo $marks === null ? "Bad marks value" : "Marks: $marks";
// --- catch failures instead of crashing ---
try {
$pdo = new PDO("mysql:host=localhost;dbname=study", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// prepared statement - the ONLY safe way to use user input in SQL
$stmt = $pdo->prepare("SELECT name, marks FROM students WHERE class = ?");
$stmt->execute([$_GET["class"] ?? ""]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log($e->getMessage()); // log it
echo "Could not load data right now."; // never show the raw error
}