PHP Evolution: Complete Guide to Changes from 7.0 to 8.3
Comprehensive breakdown of PHP changes from version 7.0 to 8.3, with practical examples and real-world use cases. Perfect for developers updating their PHP knowledge.
Hey there! Today I'm going to break down every major change in PHP from version 7.0 to 8.3. Not just listing features, but explaining why they matter and how to use them. Grab a coffee, this is gonna be a long one!
First, Some Context
Before diving into specific versions, let's understand why these changes matter. PHP 7 was a massive turning point - it literally doubled performance compared to PHP 5. Then PHP 8 came along and changed how we write code entirely with features like named arguments and attributes.
Performance Evolution
PHP 7.0's new Zend Engine was a game-changer:
- 2x faster than PHP 5.6
- Much better memory usage
- Consistent performance improvements in each version
Type System Evolution
Types in PHP went from "eh, whatever" to "actually really good":
- PHP 7.0: Basic scalar types
- PHP 7.4: Property types
- PHP 8.0: Union types
- PHP 8.1: Enums (finally!)
The Complete Changelog
Let's go through each version and what it brought us.
PHP 7.0: The Game Changer
Here's what made PHP 7.0 special:
declare(strict_types=1);
function add(int $a, int $b): int {
return $a + $b;
}
// Works
echo add(5, 10);
// Throws TypeError
echo add("5", "10");
The null coalescing operator saved us from isset() hell:
// Old way
$username = isset($_GET['user']) ? $_GET['user'] : 'guest';
// New way
$username = $_GET['user'] ?? 'guest';
PHP 7.1: Making Types Better
Nullable types were huge:
class User {
public function setName(?string $name): ?string {
if ($name === null) {
return null;
}
$this->name = $name;
return "Name set to $name";
}
}
Multi-catch made error handling less painful:
try {
// Some risky code
} catch (FirstException | SecondException $e) {
// Handle both the same way
log($e->getMessage());
}
PHP 7.4: Modern Features Arrive
Property types changed how we write classes:
class User {
public int $id;
public string $name;
private ?string $email;
protected bool $active = true;
}
Arrow functions made code shorter:
$numbers = [1, 2, 3];
// Old way
$doubled = array_map(function($n) {
return $n * 2;
}, $numbers);
// New way
$doubled = array_map(fn($n) => $n * 2, $numbers);
PHP 8.0: The Revolution
Named arguments solved the optional parameter mess:
function createUser(
string $name,
string $email,
bool $active = true,
?string $role = null
) {
// ...
}
// So much clearer!
createUser(
name: 'John',
email: 'john@example.com',
role: 'admin'
);
Match expression replaced switch and is way better:
$result = match ($status) {
200, 201 => 'Success',
400, 404 => 'Not Found',
500 => 'Server Error',
default => 'Unknown Status'
};
Constructor property promotion reduced boilerplate:
// Old way
class Point {
private float $x;
private float $y;
public function __construct(float $x, float $y) {
$this->x = $x;
$this->y = $y;
}
}
// New way
class Point {
public function __construct(
private float $x,
private float $y,
) {}
}
PHP 8.1: Even Better Types
Enums finally arrived:
enum Status: string {
case DRAFT = 'draft';
case PUBLISHED = 'published';
case ARCHIVED = 'archived';
}
function updateStatus(Post $post, Status $status) {
$post->status = $status;
}
updateStatus($post, Status::PUBLISHED);
First class callable syntax:
// Old way
$fn = [$object, 'method'];
// New way
$fn = $object->method(...);
PHP 8.2: Fine-Tuning
Readonly classes:
readonly class UserData {
public function __construct(
public string $name,
public string $email
) {}
}
Common Gotchas
-
Strict Types
- They're not enabled by default
- Use
declare(strict_types=1);
at top of files
-
Return Types
- Can't use union types in PHP 7.x
- Void means no return, not null
-
Property Promotion
- Only works with typed properties
- Can't use with complex default values
Performance Impact
Each version got faster:
- PHP 7.0: 2x faster than 5.6
- PHP 7.4: 5-10% faster than 7.0
- PHP 8.0: JIT compiler added
- PHP 8.1+: Incremental improvements
Migration Tips
When upgrading:
- Enable error reporting:
error_reporting(E_ALL);
ini_set('display_errors', 1);
- Use static analysis:
composer require --dev phpstan/phpstan
- Test thoroughly:
composer require --dev phpunit/phpunit
Security Notes
Each version improved security:
- Better type checking
- Stricter parsing
- Improved error handling
- Better password hashing
That's all! Hope this helps someone.