Coding · Programming languages
PHP tutorial for beginners
Short answer
PHP is a server-side scripting language built for the web: a PHP file runs on the server and sends HTML or JSON to the browser. Install PHP, save <?php echo "Hello, world"; as hello.php and run php hello.php, or start a local server with php -S localhost:8000. The core ideas are $ variables, flexible arrays, functions with type declarations, classes, exceptions, and safe handling of user input.
What PHP is and what it is used for
PHP was created by Rasmus Lerdorf in 1994; the name now stands for "PHP: Hypertext Preprocessor". It runs on almost every web host and powers a large share of websites, including WordPress, Drupal and Wikipedia's MediaWiki. Developers use it for content sites, online shops, REST APIs and full web applications with frameworks such as Laravel and Symfony. Modern PHP 8 has a type system, a JIT compiler, enums, attributes and much better performance than older versions.
Install PHP and run Hello, world
Install PHP from php.net or a package manager (brew install php, sudo apt install php-cli, or a bundle such as XAMPP on Windows). Check it with php -v. PHP code goes between <?php and an optional closing ?> tag.
<?php
echo "Hello, world\n";php hello.php
# Hello, world
php -S localhost:8000 # serve the current folder at http://localhost:8000In files that contain only PHP code, leave out the closing ?> tag, so no stray whitespace is sent to the browser by accident.
Variables and basic types
Variable names start with $. Types are dynamic, but you can declare parameter and return types, and declare(strict_types=1); at the top of a file stops automatic conversions in function calls.
| Type | Example | Notes |
|---|---|---|
int | $n = 42; | 64-bit on most systems |
float | $x = 3.14; | Double precision |
string | $s = "hi $name"; | Double quotes interpolate, single quotes do not |
bool | $ok = true; | Case-insensitive keyword |
array | $a = [1, 2]; | Ordered map: list and dictionary in one |
null | $v = null; | No value |
<?php
$name = "Ada";
$count = 7;
echo "$name has $count items\n"; // Ada has 7 items
echo 'No $interpolation here' . "\n"; // No $interpolation here
echo intdiv($count, 2), " ", $count / 2, "\n"; // 3 3.5
var_dump((int) "12" + 1); // int(13)The . operator joins strings; + is only for numbers.
Control flow
<?php
$score = 72;
if ($score >= 90) {
echo "A\n";
} elseif ($score >= 70) {
echo "B\n"; // B
} else {
echo "C\n";
}
for ($i = 0; $i < 3; $i++) {
echo $i, " "; // 0 1 2
}
echo "\n";
foreach (["apple", "pear"] as $fruit) {
echo $fruit, "\n";
}
$kind = match ($day = "SAT") { // match is strict and returns a value
"SAT", "SUN" => "weekend",
default => "weekday",
};
echo $kind, "\n"; // weekendmatch (PHP 8.0 and later) compares with === and throws an error when no arm matches, unlike the older switch, which compares loosely and falls through without break.
Functions
<?php
declare(strict_types=1);
function greet(string $name, string $greeting = "Hello"): string
{
return "$greeting, $name!";
}
echo greet("Lin"), "\n"; // Hello, Lin!
echo greet(greeting: "Hi", name: "Lin"), "\n"; // Hi, Lin! (named arguments)
$square = fn(int $x): int => $x * $x; // arrow function
echo $square(5), "\n"; // 25
function total(int ...$nums): int // variadic
{
return array_sum($nums);
}
echo total(1, 2, 3), "\n"; // 6Signature feature: arrays
The PHP array is one flexible type that works as a list, a dictionary, a stack or a queue. Keys are integers or strings, and insertion order is kept. A large set of built-in functions works on arrays.
<?php
$nums = [3, 1, 2];
$nums[] = 5; // append
sort($nums);
echo implode(", ", $nums), "\n"; // 1, 2, 3, 5
$ages = ["ann" => 31, "bob" => 25];
$ages["cy"] = 40;
foreach ($ages as $person => $age) {
echo "$person is $age\n";
}
echo $ages["zed"] ?? 0, "\n"; // 0 (null coalescing)
$evens = array_filter($nums, fn($n) => $n % 2 === 0);
$squares = array_map(fn($n) => $n * $n, $nums);
echo json_encode(array_values($evens)), " ", json_encode($squares), "\n"; // [2] [1,4,9,25]
echo count($ages), " ", array_key_exists("bob", $ages) ? "yes" : "no", "\n"; // 3 yesArrays are copied on assignment (copy-on-write), unlike objects, which are passed by handle.
Classes, constructor promotion and enums
<?php
declare(strict_types=1);
enum Role: string
{
case Admin = "admin";
case Viewer = "viewer";
}
final class User
{
public function __construct(
public readonly string $name,
public readonly Role $role = Role::Viewer,
) {}
public function label(): string
{
return "{$this->name} ({$this->role->value})";
}
}
$u = new User("Ann", Role::Admin);
echo $u->label(), "\n"; // Ann (admin)
echo Role::from("viewer")->name, "\n"; // ViewerConstructor promotion (PHP 8.0) declares and assigns properties in the constructor signature. readonly properties (8.1) can be set once, and backed enums (8.1) map cases to strings or integers. Interfaces, abstract classes and traits are also available.
Error handling
Modern PHP throws exceptions for most errors. Catch Exception subclasses for expected failures; Throwable also covers engine errors such as TypeError.
<?php
function parseAge(string $text): int
{
if (!ctype_digit($text)) {
throw new InvalidArgumentException("invalid age: $text");
}
return (int) $text;
}
try {
echo parseAge("41"), "\n"; // 41
echo parseAge("abc"), "\n";
} catch (InvalidArgumentException $e) {
echo $e->getMessage(), "\n"; // invalid age: abc
} finally {
echo "done\n";
}A small complete program: a JSON API endpoint
Save this as api.php, run php -S localhost:8000, and open http://localhost:8000/api.php?name=Ann. It reads a query parameter, validates it and returns JSON.
<?php
declare(strict_types=1);
header("Content-Type: application/json; charset=utf-8");
$name = trim($_GET["name"] ?? "");
if ($name === "" || mb_strlen($name) > 50) {
http_response_code(400);
echo json_encode(["error" => "name must be 1 to 50 characters"]);
exit;
}
$response = [
"message" => "Hello, $name!",
"length" => mb_strlen($name),
"time" => date(DATE_ATOM),
];
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);$_GET, $_POST and $_COOKIE hold request data. Treat every value in them as untrusted.
Common beginner mistakes
- Comparing with
==, which converts types; use===and!==. - Forgetting the
$on a variable name, or the semicolon at the end of a statement. - Storing passwords with
md5orsha1. Usepassword_hashandpassword_verify. - Using
strlenon UTF-8 text; it counts bytes. Usemb_strlenfor characters. - Running an old PHP version. Use a supported PHP 8 release for security fixes and modern features.
Where to go next
The official PHP Manual on php.net documents every function, with a language reference and user notes. Learn Composer, the package manager, and PSR coding standards, then try a framework: Laravel or Symfony for applications, or Slim for small APIs. PHPUnit is the standard testing tool.
FAQ
Is PHP still worth learning?
Yes. It runs a large part of the web, including WordPress sites, and modern PHP 8 with Laravel or Symfony is a productive way to build web applications. Jobs maintaining and building PHP systems are common.
Is PHP a frontend or backend language?
Backend. PHP runs on the server and sends the finished HTML, JSON or files to the browser, which never sees the PHP code.
What is the difference between echo and print?
Both output text. echo can take several comma-separated arguments and returns nothing; print takes one argument and returns 1. In practice most code uses echo.
What does declare(strict_types=1) do?
It makes scalar type declarations strict for function calls made from that file, so passing the string "5" to an int parameter throws a TypeError instead of being converted.