Skip to content

发展历史与版本

PHP 诞生于 1995 年,从最初的一个简单工具发展为当今世界上使用最广泛的 Web 编程语言之一。在近三十年的发展历程中,PHP 经历了多次重大版本迭代,每一次都带来了显著的语言改进和性能提升。本节将回顾 PHP 的完整发展历史,并详细介绍从 PHP 8.0 到 PHP 8.4 的核心新特性。

前置知识

本节主要介绍 PHP 的历史和发展脉络,无需特殊前置知识。如果你想了解 PHP 当前的能力,建议先阅读 PHP 是什么PHP 能做什么

基础概念

PHP 的起源

PHP 的故事始于 1994 年。当时,丹麦籍程序员 Rasmus Lerdorf 用 C 语言编写了一组 Perl CGI 脚本,用来追踪他自己简历的访问者。他将这套脚本命名为 Personal Home Page Tools(个人主页工具),这就是 PHP 最早的名字。

1995 年,Rasmus 将这些脚本重写为 C 语言实现,并开源发布,称为 PHP/FI(Personal Home Page / Forms Interpreter)。PHP/FI 2.0 是第一个公开发布的版本,它已经具备了基本的表单处理、数据库交互和变量使用能力。

版本命名与发布周期

PHP 的版本命名经历了以下演变:

时期版本名称含义
1995PHP/FIPersonal Home Page / Forms Interpreter
1997PHP 3PHP: Hypertext Preprocessor(正式确立缩写)
2000PHP 4引入 Zend Engine
2004PHP 5面向对象编程的重大改进
2015PHP 7性能革命(PHP 6 跳过)
2020PHP 8现代化特性(JIT、命名参数、属性等)

自 PHP 7.0 起,PHP 采用了年度发布的节奏(每年 11 月底或 12 月初发布新版本),每个大版本支持 2 年的活跃更新和 1 年的安全修复。这种节奏使得 PHP 能够持续快速地引入新特性。

详细说明 — 各版本发展历程

PHP/FI(1995-1997)

PHP/FI 是 PHP 的雏形版本,具有以下特征:

  • 支持嵌入 HTML 的脚本语法
  • 支持基本的表单处理(这是「FI」的由来)
  • 支持与 mSQL 数据库的交互
  • 支持变量(以 $ 开头的变量语法从此时确立)
  • 使用类似 Perl 的语法风格

PHP 3(1998-2000)

PHP 3 是一个里程碑式的版本,由 Zeev SuraskiAndi Gutmans 对 PHP/FI 进行了全面重写:

  • 全新设计了 PHP 的解析器,执行速度大幅提升
  • 正式确立了 PHP: Hypertext Preprocessor 的递归缩写
  • 引入了初步的面向对象编程支持(类和对象的基本概念)
  • 支持 HTTP Session 管理
  • 支持多种数据库(MySQL、PostgreSQL、Oracle 等)
  • 引入了扩展 API,使第三方开发者能够编写 PHP 扩展

PHP 4(2000-2005)

PHP 4 引入了 Zend Engine 1.0,这是 PHP 的核心执行引擎:

  • Zend Engine 带来了更快的执行速度和更高的稳定性
  • 引入了 $_GET$_POST$_SESSION 等超全局变量
  • 支持引用计数(Reference Counting)的内存管理
  • 引入了输出缓冲控制(Output Buffering)
  • 支持更完善的面向对象特性(构造函数、析构函数)
  • 广泛的数据库扩展支持
php
<?php
declare(strict_types=1);

// PHP 4 时代的典型代码风格
// 注意:这种风格在现代 PHP 中已不推荐
class OldStyle
{
    var $name; // var 关键字声明属性(PHP 4 风格,现已弃用)

    // PHP 4 构造函数风格(与类同名)
    function OldStyle($name)
    {
        $this->name = $name;
    }

    function getName()
    {
        return $this->name;
    }
}

// 现代 PHP 等价写法
class ModernStyle
{
    public function __construct(
        private readonly string $name
    ) {
    }

    public function getName(): string
    {
        return $this->name;
    }
}

echo "PHP 4 风格 (已过时):\n";
$old = new OldStyle('PHP 4');
echo "Name: " . $old->getName() . "\n\n";

echo "现代 PHP 风格:\n";
$modern = new ModernStyle('PHP 8');
echo "Name: " . $modern->getName() . "\n";

PHP 5(2004-2015)

PHP 5 引入了 Zend Engine 2.0,是 PHP 面向对象编程的一次重大飞跃:

特性说明
访问修饰符publicprotectedprivate
抽象类与接口完整的 OOP 支持
final 关键字防止类或方法被继承/覆盖
异常处理try/catch/finally
SPL(标准 PHP 库)迭代器、过滤器等数据结构
PDO(PHP 数据对象)统一的数据库访问层
类型提示函数参数的类型声明(PHP 5.1)
命名空间避免类名冲突(PHP 5.3)
闭包/匿名函数函数式编程支持(PHP 5.3)
Trait代码复用机制(PHP 5.4)
生成器内存友好的迭代(PHP 5.5)
严格标量类型declare(strict_types=1)(PHP 5.6)
php
<?php
declare(strict_types=1);

// PHP 5 时代引入的 OOP 特性综合示例

interface Loggable
{
    public function getLogMessage(): string;
}

abstract class Entity
{
    public function __construct(
        protected readonly int $id,
        protected readonly string $createdAt
    ) {
    }

    abstract public function toArray(): array;

    public function getId(): int
    {
        return $this->id;
    }
}

// Trait — PHP 5.4 引入
trait Timestampable
{
    protected ?string $updatedAt = null;

    public function touch(): void
    {
        $this->updatedAt = date('Y-m-d H:i:s');
    }

    public function getUpdatedAt(): ?string
    {
        return $this->updatedAt;
    }
}

// 生成器 — PHP 5.5 引入
class User extends Entity implements Loggable
{
    use Timestampable;

    public function __construct(
        int $id,
        string $createdAt,
        private readonly string $name,
        private readonly string $email
    ) {
        parent::__construct($id, $createdAt);
    }

    public function getLogMessage(): string
    {
        return "用户 {$this->name} (ID: {$this->id})";
    }

    public function toArray(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'createdAt' => $this->createdAt,
        ];
    }
}

// 使用生成器产生大量数据,内存友好
function generateUserIds(int $count): \Generator
{
    for ($i = 1; $i <= $count; $i++) {
        yield $i;
    }
}

// 演示
$user = new User(1, '2024-01-01', '张三', 'zhangsan@example.com');
$user->touch();
echo $user->getLogMessage() . "\n";
echo "最后更新: " . $user->getUpdatedAt() . "\n";

echo "\n生成器演示 (前 5 个):\n";
foreach (generateUserIds(1000000) as $id) {
    echo "ID: {$id}\n";
    if ($id >= 5) break;
}

PHP 7(2015-2019)

PHP 7 是一次性能和语言的革命性升级,执行速度比 PHP 5.6 快了两倍以上:

特性版本说明
性能提升7.0Zend Engine 3,性能提升约 2x
标量类型声明7.0intfloatstringbool
返回值类型声明7.0函数可以声明返回类型
null 合并运算符7.0??
太空船运算符7.0<=> 三路比较
匿名类7.0支持创建未命名类
Throwable 接口7.0统一的错误/异常处理
标量返回类型7.1void 返回类型
可空类型7.1?int 等可空类型声明
iterable 伪类型7.1可迭代的类型声明
多异常捕获7.1`catch (A
对称数组解构7.1[$a, $b] = $array
类型声明强化7.2object 类型
参数类型 widening7.2子类参数类型可以更宽松
Argon2 密码哈希7.2更安全的密码哈希算法
php
<?php
declare(strict_types=1);

// PHP 7 的核心特性演示

// 标量类型声明 + 返回值类型(PHP 7.0)
function calculateTotal(int $price, int $quantity): int
{
    return $price * $quantity;
}

// null 合并运算符(PHP 7.0)
function getConfigValue(array $config, string $key, string $default = 'N/A'): string
{
    return $config[$key] ?? $default;
}

// 太空船运算符(PHP 7.0)
function compareVersions(string $a, string $b): int
{
    return version_compare($a, $b); // 返回 -1, 0, 1
}

// 可空类型 + void 返回类型(PHP 7.1)
function findUserById(int $id): ?array
{
    $users = [
        1 => ['id' => 1, 'name' => '张三'],
        2 => ['id' => 2, 'name' => '李四'],
    ];

    return $users[$id] ?? null;
}

function logMessage(string $message): void
{
    $timestamp = date('Y-m-d H:i:s');
    echo "[{$timestamp}] {$message}\n";
}

// 多异常捕获(PHP 7.1)
try {
    $result = 10 / 0;
} catch (DivisionByZeroError | ArithmeticError $e) {
    logMessage("计算错误: " . $e->getMessage());
}

// 对称数组解构(PHP 7.1)
$coordinates = ['latitude' => 39.9, 'longitude' => 116.4];
['latitude' => $lat, 'longitude' => $lng] = $coordinates;
echo "坐标: {$lat}, {$lng}\n";

// 匿名类(PHP 7.0)
$logger = new class {
    public function log(string $message): void
    {
        echo "[LOG] {$message}\n";
    }
};
$logger->log("这是一条匿名类日志");

PHP 8(2020 至今)— 现代化新纪元

PHP 8 是 PHP 发展史上又一个重大里程碑版本,引入了 JIT 编译器、命名参数、属性(注解)、联合类型、match 表达式等众多现代语言特性。以下详细介绍 PHP 8.0 到 PHP 8.4 的核心新特性。

PHP 8 各版本核心新特性

PHP 8.0 — 里程碑版本

特性说明
JIT(Just-In-Time)编译器将热点函数编译为机器码,显著提升 CPU 密集型任务的性能
命名参数(Named Arguments)通过参数名传值,不再受顺序限制
联合类型(Union Types)类型声明支持多种类型,如 int|float
Match 表达式更安全的 switch 替代品
Null 安全运算符?-> 简化 null 检查链
属性(Attributes)原生注解支持,替代 PHPDoc 注解
构造器属性提升在构造函数中直接声明和初始化属性
str_contains() 等新函数更直观的字符串操作函数
mixed 类型显式声明混合类型
static 返回类型返回值类型声明支持延迟静态绑定
WeakMap弱引用映射,避免内存泄漏
ValueError值参数验证异常类
php
<?php
declare(strict_types=1);

// PHP 8.0 新特性演示

// 命名参数
function createUser(
    string $name,
    string $email,
    string $role = 'user',
    bool $isActive = true
): array {
    return compact('name', 'email', 'role', 'isActive');
}

// 使用命名参数,可以跳过中间的参数
$user = createUser(
    email: 'admin@example.com',
    name: '管理员',
    role: 'admin'
);
print_r($user);

// 联合类型
function parseInput(int|string $input): int
{
    if (is_string($input)) {
        return (int) filter_var($input, FILTER_SANITIZE_NUMBER_INT);
    }
    return $input;
}

// Match 表达式
$httpCode = 200;
$statusText = match ($httpCode) {
    200, 201, 204 => '成功',
    301, 302 => '重定向',
    400 => '错误请求',
    401 => '未授权',
    403 => '禁止访问',
    404 => '未找到',
    500 => '服务器错误',
    default => '未知状态',
};
echo "HTTP {$httpCode}: {$statusText}\n";

// Null 安全运算符
$country = null;
$region = null;
$city = $country?->region?->city ?? '未知城市';
echo "城市: {$city}\n";

// 属性(Attributes)
#[Attribute]
class Route
{
    public function __construct(
        public readonly string $path,
        public readonly string $method = 'GET'
    ) {
    }
}

#[Route(path: '/api/users', method: 'GET')]
function getUsers(): array
{
    return ['user1', 'user2', 'user3'];
}

// 构造器属性提升
class Point
{
    public function __construct(
        public readonly float $x,
        public readonly float $y
    ) {
    }
}

$p = new Point(1.5, 2.5);
echo "点坐标: ({$p->x}, {$p->y})\n";

// str_contains 等新字符串函数
$haystack = 'Hello, PHP 8.0!';
echo "包含 'PHP': " . (str_contains($haystack, 'PHP') ? '是' : '否') . "\n";
echo "以 'Hello' 开头: " . (str_starts_with($haystack, 'Hello') ? '是' : '否') . "\n";
echo "以 '!' 结尾: " . (str_ends_with($haystack, '!') ? '是' : '否') . "\n";

PHP 8.1 — 枚举与纤程

特性说明
枚举(Enums)原生枚举类型,支持接口、方法
只读属性(Readonly Properties)属性只能初始化一次
纤程(Fibers)协程/轻量级线程支持
交集类型(Intersection Types)类型声明支持多类型交集,如 A&B
never 返回类型表示函数永不返回
final 类的常量final 类中可以声明常量
新的 readonly 转为属性
array_is_list()检查数组是否是 0-indexed 列表
fsync()/fdatasync()文件同步函数
php
<?php
declare(strict_types=1);

// PHP 8.1 新特性演示

// 枚举(Enums)
enum HttpMethod: string
{
    case Get = 'GET';
    case Post = 'POST';
    case Put = 'PUT';
    case Delete = 'DELETE';
    case Patch = 'PATCH';

    public function isSafe(): bool
    {
        return match ($this) {
            self::Get, self::Head => true,
            default => false,
        };
    }

    public function description(): string
    {
        return match ($this) {
            self::Get => '获取资源',
            self::Post => '创建资源',
            self::Put => '更新资源',
            self::Delete => '删除资源',
            self::Patch => '部分更新',
        };
    }
}

$method = HttpMethod::Get;
echo "方法: {$method->value}\n";
echo "安全: " . ($method->isSafe() ? '是' : '否') . "\n";
echo "描述: {$method->description()}\n";

// 只读属性
class Configuration
{
    public function __construct(
        public readonly string $appName,
        public readonly string $appEnv,
        public readonly bool $debug,
        public readonly int $port = 8080
    ) {
    }
}

$config = new Configuration('MyApp', 'production', false, 443);
echo "应用: {$config->appName} ({$config->appEnv})\n";

// 交集类型
interface CountableContainer
{
    public function count(): int;
}

interface IteratorAggregate
{
    public function getIterator(): \ArrayIterator;
}

class Collection implements CountableContainer, IteratorAggregate
{
    private array $items = [];

    public function add(string $item): void
    {
        $this->items[] = $item;
    }

    public function count(): int
    {
        return count($this->items);
    }

    public function getIterator(): \ArrayIterator
    {
        return new \ArrayIterator($this->items);
    }
}

// never 返回类型 — 表示函数绝不正常返回
function handleNotFound(): never
{
    http_response_code(404);
    echo '<h1>404 Not Found</h1>';
    exit;
}

// array_is_list
$arr1 = ['a', 'b', 'c'];
$arr2 = [0 => 'a', 1 => 'b', 2 => 'c'];
$arr3 = [0 => 'a', 2 => 'b']; // 跳过了索引 1

echo "arr1 是列表: " . (array_is_list($arr1) ? '是' : '否') . "\n";
echo "arr2 是列表: " . (array_is_list($arr2) ? '是' : '否') . "\n";
echo "arr3 是列表: " . (array_is_list($arr3) ? '是' : '否') . "\n";

PHP 8.2 — 只读类与析构嵌套

特性说明
只读类(Readonly Classes)整个类的所有属性都是只读的
析构嵌套(DNF Types)组合联合类型和交集类型,如 (A&B)|C
参数中的 ... 展示可以将命名参数传递给可变参数函数
#[\AllowDynamicProperties]标注允许动态属性的类
#[\SensitiveParameter]敏感参数不会出现在堆栈跟踪中
新的随机数扩展对象化的随机数生成器
odometer trait 弃用
trait 中的常量Trait 中可以定义常量
php
<?php
declare(strict_types=1);

// PHP 8.2 新特性演示

// 只读类
readonly class DtoUser
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age
    ) {
    }
}

$userDto = new DtoUser('张三', 'zhangsan@example.com', 30);
echo "用户: {$userDto->name}, 年龄: {$userDto->age}\n";

// DNF 类型 (Disjunctive Normal Form Types)
function processResource(string|array|int $input): string
{
    if (is_string($input)) {
        return "字符串: {$input}";
    }
    if (is_int($input)) {
        return "整数: {$input}";
    }
    if (is_array($input)) {
        return "数组: " . json_encode($input, JSON_UNESCAPED_UNICODE);
    }
    return "未知类型";
}

echo processResource("hello") . "\n";
echo processResource(42) . "\n";
echo processResource(['key' => 'value']) . "\n";

// 新的随机数扩展
use Random\Randomizer;

$randomizer = new Randomizer();

// 生成随机整数
$randomInt = $randomizer->getInt(1, 100);
echo "随机整数 (1-100): {$randomInt}\n";

// 从数组中随机选择一个元素
$options = ['苹果', '香蕉', '橙子', '葡萄'];
$fruit = $randomizer->pickArrayValues($options, 1);
echo "随机水果: {$fruit[0]}\n";

// 生成随机字节(适合生成密码/令牌)
$bytes = $randomizer->getBytes(16);
$token = bin2hex($bytes);
echo "随机令牌: {$token}\n";

// 敏感参数 — 在堆栈跟踪中隐藏
function connectToDatabase(
    string $host,
    string $username,
    #[\SensitiveParameter]
    string $password
): void
{
    echo "连接到 {$host} 用户 {$username}\n";
    // password 不会出现在错误堆栈中
}

PHP 8.3 — 类型化类常量与改进

特性说明
类型化类常量类常量可以声明类型
动态类常量获取Foo::{$bar} 语法
#[\Override] 属性标明方法覆盖了父类方法
json_validate()验证字符串是否为有效的 JSON
新的 Random 方法getBytesFromString()
clone 操作符可用 readonly
堆栈跟踪改进更详细的错误堆栈信息
php
<?php
declare(strict_types=1);

// PHP 8.3 新特性演示

// 类型化类常量
class ApiVersion
{
    public const string V1 = 'v1';
    public const string V2 = 'v2';
    public const int MAX_ITEMS = 100;
    public const string CURRENT = self::V2;
}

echo "当前 API 版本: " . ApiVersion::CURRENT . "\n";
echo "最大条目数: " . ApiVersion::MAX_ITEMS . "\n";

// 动态类常量获取
class Status
{
    public const ACTIVE = 'active';
    public const INACTIVE = 'inactive';
    public const PENDING = 'pending';
}

$statusField = 'ACTIVE';
$statusCode = Status::{$statusField};
echo "状态: {$statusCode}\n";

// json_validate() — PHP 8.3 新增
$jsonStrings = [
    '{"name": "张三", "age": 30}',
    '{"name": "李四", "age": }', // 无效 JSON
    'not json at all',
];

foreach ($jsonStrings as $json) {
    $isValid = json_validate($json);
    echo "JSON 有效: " . ($isValid ? '是' : '否') . " — {$json}\n";
}

// #[\Override] 属性
abstract class BaseService
{
    public function initialize(): void
    {
        echo "BaseService 初始化\n";
    }

    public function process(): string
    {
        return 'base process';
    }
}

class UserService extends BaseService
{
    #[\Override]
    public function initialize(): void
    {
        echo "UserService 初始化\n";
        parent::initialize();
    }

    #[\Override]
    public function process(): string
    {
        return 'user process';
    }
}

$service = new UserService();
$service->initialize();
echo "处理结果: " . $service->process() . "\n";

PHP 8.4 — 属性钩子与新的数组函数

特性说明
属性钩子(Property Hooks)__get/__set 的语法糖,更优雅的属性访问控制
Asymmetric Visibility不对称可见性,如 public private(set)
新的数组函数array_find()array_find_key()array_any()array_all()
带闭包的 new 表达式new Foo(function() {})
parse_url() 改进返回组件数组而非 null
html_entity_decode() 改进
mb_str_pad()
php
<?php
declare(strict_types=1);

// PHP 8.4 新特性演示

// 属性钩子(Property Hooks)
class Temperature
{
    public float $celsius {
        get {
            return $this->_celsius;
        }
        set(float $value) {
            if ($value < -273.15) {
                throw new \ValueError('温度不能低于绝对零度 (-273.15 C)');
            }
            $this->_celsius = $value;
        }
    }

    // 虚拟属性(无后备字段)
    public float $fahrenheit {
        get => $this->_celsius * 9 / 5 + 32;
        set => $this->_celsius = ($value - 32) * 5 / 9;
    }

    private float $_celsius = 0.0;

    public function __construct(float $celsius = 0.0)
    {
        $this->_celsius = $celsius;
    }
}

// 注意:属性钩子目前仅作为示例展示 PHP 8.4 的特性
echo "=== PHP 8.4 新特性 ===\n";
echo "属性钩子允许为属性定义自定义的 get/set 行为\n";

// 不对称可见性(PHP 8.4)
class BankAccount
{
    // 外部可读,只能内部写入
    public string $accountNumber {
        public readonly get => $this->_accountNumber;
    }

    public float $balance {
        public get => $this->_balance;
        private set => $this->_balance = $value;
    }

    private string $_accountNumber;
    private float $_balance = 0.0;

    public function __construct(string $accountNumber)
    {
        $this->_accountNumber = $accountNumber;
    }

    public function deposit(float $amount): void
    {
        if ($amount <= 0) {
            throw new \ValueError('存款金额必须大于 0');
        }
        $this->_balance += $amount;
    }

    public function withdraw(float $amount): void
    {
        if ($amount <= 0) {
            throw new \ValueError('取款金额必须大于 0');
        }
        if ($amount > $this->_balance) {
            throw new \ValueError('余额不足');
        }
        $this->_balance -= $amount;
    }
}

echo "不对称可见性: 外部可读 private(set)\n";

// 新的数组函数(PHP 8.4)
$users = [
    ['id' => 1, 'name' => '张三', 'role' => 'admin'],
    ['id' => 2, 'name' => '李四', 'role' => 'user'],
    ['id' => 3, 'name' => '王五', 'role' => 'admin'],
    ['id' => 4, 'name' => '赵六', 'role' => 'user'],
];

// array_find — 查找第一个匹配的元素
$admin = array_find($users, fn($u) => $u['role'] === 'admin');
echo "第一个管理员: " . ($admin['name'] ?? '未找到') . "\n";

// array_find_key — 查找第一个匹配的键
$adminKey = array_find_key($users, fn($u) => $u['role'] === 'admin');
echo "管理员键名: {$adminKey}\n";

// array_any — 是否有任何元素满足条件
$hasAdmin = array_any($users, fn($u) => $u['role'] === 'admin');
echo "有管理员: " . ($hasAdmin ? '是' : '否') . "\n";

// array_all — 是否所有元素都满足条件
$allActive = array_all($users, fn($u) => isset($u['name']));
echo "全部有效: " . ($allActive ? '是' : '否') . "\n";

PHP 8.x 版本特性速查表

特性PHP 8.0PHP 8.1PHP 8.2PHP 8.3PHP 8.4
JIT 编译器Yes----
命名参数Yes----
联合类型Yes----
Match 表达式Yes----
Null 安全运算符Yes----
属性(Attributes)Yes----
构造器属性提升Yes----
str_containsYes----
枚举-Yes---
只读属性-Yes---
纤程(Fibers)-Yes---
交集类型-Yes---
never 返回类型-Yes---
只读类--Yes--
DNF 类型--Yes--
新随机数扩展--Yes--
敏感参数--Yes--
类型化类常量---Yes-
json_validate---Yes-
#[\Override]---Yes-
属性钩子----Yes
不对称可见性----Yes
array_find 等新函数----Yes

当前版本选择建议

生产环境推荐

版本推荐(截至 2026 年)

  • 首选推荐:PHP 8.3 LTS(长期支持)
  • 次选:PHP 8.2(稳定)
  • 尝鲜:PHP 8.4(最新)

版本生命周期

PHP 的版本支持周期如下:

版本发布日期活跃支持截止安全支持截止状态
PHP 8.12021-112023-112024-12安全修复结束
PHP 8.22022-122024-122025-12安全修复中
PHP 8.32023-112025-112026-12活跃支持中
PHP 8.42024-112026-112027-12活跃支持中

版本选择原则

php
<?php
declare(strict_types=1);

// 版本选择建议工具
class VersionRecommender
{
    public function recommend(string $scenario): string
    {
        return match ($scenario) {
            'new-project' => 'PHP 8.3+ — 新项目建议使用最新的稳定版本',
            'legacy-project' => '至少升级到 PHP 8.1 — 最低要求',
            'production' => 'PHP 8.3 LTS — 生产环境推荐使用 LTS 版本',
            'learning' => 'PHP 8.3 — 学习时使用最新稳定版,体验全部新特性',
            'high-performance' => 'PHP 8.3+ with JIT — 启用 JIT 以获得最佳性能',
            'shared-hosting' => '取决于主机支持的版本,最低 PHP 8.1',
            default => 'PHP 8.3 — 通用推荐',
        };
    }

    public function checkPhpVersion(): array
    {
        $versionId = PHP_VERSION_ID;

        if ($versionId < 80100) {
            return [
                'status' => 'unsupported',
                'message' => "PHP " . PHP_VERSION . " 已不再受支持,请立即升级到 PHP 8.1+",
                'recommended' => '8.3',
            ];
        }

        if ($versionId < 80200) {
            return [
                'status' => 'eol',
                'message' => "PHP " . PHP_VERSION . " 已结束安全支持",
                'recommended' => '8.3',
            ];
        }

        return [
            'status' => 'supported',
            'message' => "PHP " . PHP_VERSION . " 受到支持",
            'recommended' => '8.3',
        ];
    }
}

$recommender = new VersionRecommender();

// 输出当前 PHP 版本检查结果
$check = $recommender->checkPhpVersion();
echo "=== PHP 版本检查 ===\n";
echo "当前版本: " . PHP_VERSION . " (ID: " . PHP_VERSION_ID . ")\n";
echo "状态: {$check['status']}\n";
echo "建议: {$check['message']}\n";

实战示例

PHP 版本特性检测工具

php
<?php
declare(strict_types=1);

/**
 * PHP 版本特性检测工具
 * 检测当前 PHP 版本支持哪些特性
 */

class FeatureDetector
{
    private array $features = [];

    public function __construct()
    {
        $this->features = [
            'named_args' => [
                'min_version' => '8.0',
                'name' => '命名参数',
                'check' => fn(): bool => PHP_VERSION_ID >= 80000,
            ],
            'union_types' => [
                'min_version' => '8.0',
                'name' => '联合类型',
                'check' => fn(): bool => PHP_VERSION_ID >= 80000,
            ],
            'match' => [
                'min_version' => '8.0',
                'name' => 'Match 表达式',
                'check' => fn(): bool => PHP_VERSION_ID >= 80000,
            ],
            'attributes' => [
                'min_version' => '8.0',
                'name' => '属性(Attributes)',
                'check' => fn(): bool => PHP_VERSION_ID >= 80000,
            ],
            'constructor_promotion' => [
                'min_version' => '8.0',
                'name' => '构造器属性提升',
                'check' => fn(): bool => PHP_VERSION_ID >= 80000,
            ],
            'null_safe_operator' => [
                'min_version' => '8.0',
                'name' => 'Null 安全运算符',
                'check' => fn(): bool => PHP_VERSION_ID >= 80000,
            ],
            'fibers' => [
                'min_version' => '8.1',
                'name' => '纤程(Fibers)',
                'check' => fn(): bool => PHP_VERSION_ID >= 80100,
            ],
            'enums' => [
                'min_version' => '8.1',
                'name' => '枚举(Enums)',
                'check' => fn(): bool => PHP_VERSION_ID >= 80100,
            ],
            'readonly_props' => [
                'min_version' => '8.1',
                'name' => '只读属性',
                'check' => fn(): bool => PHP_VERSION_ID >= 80100,
            ],
            'intersection_types' => [
                'min_version' => '8.1',
                'name' => '交集类型',
                'check' => fn(): bool => PHP_VERSION_ID >= 80100,
            ],
            'readonly_classes' => [
                'min_version' => '8.2',
                'name' => '只读类',
                'check' => fn(): bool => PHP_VERSION_ID >= 80200,
            ],
            'dnf_types' => [
                'min_version' => '8.2',
                'name' => 'DNF 类型',
                'check' => fn(): bool => PHP_VERSION_ID >= 80200,
            ],
            'json_validate' => [
                'min_version' => '8.3',
                'name' => 'json_validate()',
                'check' => fn(): bool => PHP_VERSION_ID >= 80300,
            ],
            'typed_constants' => [
                'min_version' => '8.3',
                'name' => '类型化类常量',
                'check' => fn(): bool => PHP_VERSION_ID >= 80300,
            ],
            'property_hooks' => [
                'min_version' => '8.4',
                'name' => '属性钩子',
                'check' => fn(): bool => PHP_VERSION_ID >= 80400,
            ],
            'asymmetric_visibility' => [
                'min_version' => '8.4',
                'name' => '不对称可见性',
                'check' => fn(): bool => PHP_VERSION_ID >= 80400,
            ],
        ];
    }

    public function checkAll(): void
    {
        echo "PHP " . PHP_VERSION . " 特性支持检测\n";
        echo str_repeat('-', 50) . "\n";

        $supported = 0;
        $unsupported = 0;

        foreach ($this->features as $key => $feature) {
            $isSupported = ($feature['check'])();
            $status = $isSupported ? 'OK' : 'X';
            $version = $feature['min_version'];

            echo sprintf(
                "  [%s] %-25s (PHP %s)\n",
                $status,
                $feature['name'],
                $version
            );

            if ($isSupported) {
                $supported++;
            } else {
                $unsupported++;
            }
        }

        echo str_repeat('-', 50) . "\n";
        echo "支持: {$supported} / 不支持: {$unsupported}\n";
    }
}

$detector = new FeatureDetector();
$detector->checkAll();

注意事项

  • PHP 6 被跳过:PHP 6 的开发计划因 Unicode 支持的复杂性而被放弃,为了避免与 Unicode 项目混淆,PHP 直接从 5 跳到了 7。这也是为什么不存在 PHP 6 版本。
  • 不要使用已 EOL 的版本:PHP 7.4 及更早版本已经停止支持,不再接收安全更新。继续使用这些版本存在安全风险。
  • 迁移需谨慎:从旧版本升级到新版本前,务必使用兼容性检查工具(如 PHP Compatibility Checker)扫描代码。
  • 扩展兼容性:升级 PHP 版本时,部分第三方扩展可能尚未适配新版本,需要提前确认。
  • 框架版本要求:主流 PHP 框架有其最低版本要求。例如,Laravel 11 要求 PHP 8.2+。

最佳实践

  • 始终使用受支持的 PHP 版本,优先选择当前活跃支持的版本。
  • composer.json 中指定 PHP 版本的最低要求:"php": "^8.1"
  • 在 CI/CD 流水线中测试多个 PHP 版本,确保兼容性。
  • 关注 PHP RFC(Request for Comments)页面,提前了解即将引入的新特性。
  • 升级时使用渐进式策略:先在开发环境测试,再逐步推广到生产环境。
  • 使用 PHP 原生特性(如枚举、只读属性)替代自定义实现,减少代码复杂度。

下一节

了解了 PHP 的发展历史和版本特性之后,让我们开始动手实践。下一节 基础交互脚本 将带你编写第一个 PHP 脚本。

参考链接