Skip to content

弃用与移除功能清单

PHP 在每个新版本中都会废弃一些旧功能和标记一些行为变更。了解这些变更对于平滑升级至关重要。本节汇总了 PHP 7.4 到 8.4 各版本中被废弃和移除的功能,提供对应的替代方案。

前置知识

阅读本节前,建议先了解:版本迁移指南

PHP 8.4 弃用功能

隐式可空类型参数

php
<?php
declare(strict_types=1);

// ❌ PHP 8.4 废弃
function foo(int|null $x = null) {}

// ✅ 替代方案
function foo(?int $x = null) {}

// ❌ 废弃
function bar(string|null $s = null) {}

// ✅ 替代
function bar(?string $s = null) {}

// ❌ 废弃
function baz(array|null $a = null) {}

// ✅ 替代
function baz(?array $a = null) {}

其他 PHP 8.4 废弃

php
<?php
declare(strict_types=1);

// 1. 未通过引用传递给函数的 null 参数
// ❌ 废弃
function foo(&$x) {}
foo(null);

// 2. $_SESSION 弃用警告(在某些场景)
// 3. 在 SplFixedArray 上使用整数键的某些行为变更

PHP 8.3 弃用功能

动态属性(进一步强化)

php
<?php
declare(strict_types=1);

// PHP 8.2 引入弃用警告
// PHP 9.0 将移除

class User
{
    public string $name;
}

$user = new User();
$user->name = 'John';    // ✅ 已声明属性
$user->age = 25;          // ⚠️ PHP 8.2+: Deprecated: dynamic property
$user->extra = 'data';   // ⚠️ PHP 8.2+: Deprecated: dynamic property

// 解决方案 1:声明所有属性
class UserFixed
{
    public string $name;
    public int $age = 0;
    public string $extra = '';
}

// 解决方案 2:使用 AllowDynamicProperties
#[\AllowDynamicProperties]
class UserDynamic
{
    public string $name;
}

$user = new UserDynamic();
$user->age = 25;  // ✅ 不再警告

get_class() 在未绑定闭包中

php
<?php
declare(strict_types=1);

// PHP 8.3 变更:在未绑定的闭包中调用 get_class() 不再返回 null
// 之前返回 null,现在抛出 Error

$fn = function () {
    // PHP 8.2: get_class() → null
    // PHP 8.3: get_class() → Error
};
$fn();

PHP 8.2 弃用功能

动态属性弃用

php
<?php
declare(strict_types=1);

// 见 PHP 8.3 部分(首次引入弃用)

部分字符串敏感函数参数变更

php
<?php
declare(strict_types=1);

// 1. htmlentities() 的 default_encoding 弃用
// 2. mb_encode_numericentity() 参数变更
// 3. trim() 等字符串函数只处理单字节字符

PHP 8.1 弃用功能

Serializable 接口

php
<?php
declare(strict_types=1);

// ❌ PHP 8.1 废弃
class OldClass implements Serializable
{
    public function serialize(): string { return ''; }
    public function unserialize(string $data): void {}
    public function __sleep(): array { return []; }
    public function __wakeup(): void {}
}

// ✅ 替代:使用 __serialize() 和 __unserialize()
class NewClass
{
    public function __serialize(): array
    {
        return get_object_vars($this);
    }

    public function __unserialize(array $data): void
    {
        foreach ($data as $key => $value) {
            $this->$key = $value;
        }
    }
}

utf8_encode() / utf8_decode()

php
<?php
declare(strict_types=1);

// ❌ PHP 8.1 废弃
$encoded = utf8_encode($string);
$decoded = utf8_decode($string);

// ✅ 替代:使用 mb_convert_encoding()
$encoded = mb_convert_encoding($string, 'UTF-8', mb_detect_encoding($string));
$decoded = mb_convert_encoding($string, 'ISO-8859-1', 'UTF-8');

// 或使用 intl 扩展

其他 PHP 8.1 废弃

php
<?php
declare(strict_types=1);

// 1. Closure::fromCallable() 的 $this 绑定弃用

// 2. $GLOBALS 中的间接引用
// ❌ 弃用
$GLOBALS['var'] = $value;

// 3. filter_var() FILTER_VALIDATE_URL 的域名验证变更
// 4. PDO::ATTR_STRINGIFY_FETCHES 弃用
// 5. mysqli 驱动的 persistent connections 变更

PHP 8.0 移除功能

主要移除列表

php
<?php
declare(strict_types=1);

// ===== 已移除的功能 =====

// 1. create_function()
// ❌ PHP 8.0 移除
$fn = create_function('$x', 'return $x * 2;');
// ✅ 替代:使用匿名函数
$fn = fn ($x) => $x * 2;

// 2. money_format()
// ❌ PHP 8.0 移除
$money = money_format('%i', 1234.56);
// ✅ 替代:NumberFormatter
$formatter = new NumberFormatter('zh_CN', NumberFormatter::CURRENCY);
$money = $formatter->formatCurrency(1234.56, 'CNY');

// 3. get_magic_quotes_gpc()
// ❌ PHP 8.0 移除
// 该功能在 PHP 5.4 已废弃,8.0 正式移除

// 4. get_magic_quotes_runtime()
// ❌ PHP 8.0 移除

// 5. implode() 的 $array 作为第一个参数
// ❌ PHP 8.0 移除
echo implode($array);
// ✅ 替代
echo implode('', $array);

// 6. Reflection::export()
// ❌ PHP 8.0 移除
Reflection::export(new ReflectionClass('stdClass'));
// ✅ 替代
echo new ReflectionClass('stdClass');

// 7. array_key_exists() 使用对象
// ❌ PHP 8.0 移除
// array_key_exists('key', $object);
// ✅ 替代:property_exists()

// 8. ereg_* 系列函数(7.0 已废弃)
// ❌ PHP 8.0 移除
// ✅ 替代:使用 preg_match()

// 9. mbstring.func_overload
// ❌ PHP 8.0 移除

// 10. var_import() 不再支持对象

其他 PHP 8.0 移除

php
<?php
declare(strict_types=1);

// 1. pdo_odbc.db2_instance_name ini 指令移除
// 2. com_dotnet 编译指令移除
// 3. gmp_random_seed() 参数变更
// 4. xmlrpc 扩展移至 PECL
// 5. wddx 扩展移至 PECL
// 6. __autoload() 已完全移除(使用 spl_autoload_register)

PHP 7.4 弃用功能

php
<?php
declare(strict_types=1);

// 1. Curly braces array access
$arr{0};     // ❌ 废弃
$arr[0];     // ✅ 替代

// 2. array_key_exists() → isset() 或 property_exists()
// array_key_exists() 未废弃但推荐替代

// 3.money_format() 废弃

// 4. implode() 反转参数废弃

// 5. ReflectionType::__toString() 废弃
// ✅ 替代:使用 ReflectionType->getName()

// 6. strip_tags() 带 $allowable_tags 标记

// 7. hebrevc() 函数废弃

速查表

功能废弃版本移除版本替代方案
create_function()7.28.0闭包 fn()
money_format()7.48.0NumberFormatter
get_magic_quotes_gpc()5.48.0无需替代
Reflection::export()7.48.0ReflectionClass::__toString()
implode($array)7.48.0implode('', $array)
ereg_* 系列5.37.0preg_match()
__autoload()7.27.2→移除spl_autoload_register()
$arr{0}7.48.0$arr[0]
Serializable 接口8.1未来__serialize()
utf8_encode/decode8.1未来mb_convert_encoding()
动态属性8.29.0显式声明或 AllowDynamicProperties
隐式可空参数8.4未来?Type 语法

最佳实践

  1. 定期清理:每个版本升级时清理所有废弃功能的使用
  2. 启用 deprecation 警告:开发环境开启 E_DEPRECATEDE_USER_DEPRECATED
  3. CI 中检测:使用 PHPCompatibility 在 CI 中自动检测废弃功能
  4. 提前规划:关注 PHP RFC 了解即将废弃的功能

下一节

返回:PHP 8.0 新特性 或查看 命名规范

参考链接