专注于高性能网络应用开发,核心技术包括PHP、Java、GO、NodeJS等后端语言,VUE、UNI、APP等前端开发,服务器运维、数据库、实时通信、AI等领域拥有丰富经验

PHP 7+ 新特性探索:那些好用、实用、有趣的内置函数与方法

随着PHP版本的不断迭代更新,从PHP 7.0到最新的PHP 8.x版本,PHP语言在性能、安全性和开发效率方面都有了显著提升。然而,许多开发者仍然停留在旧版本的编程习惯中,未能充分利用新版PHP提供的强大内置函数和方法。这不仅导致代码冗余、性能低下,也错失了简化代码逻辑、提高开发效率的机会。

本文将系统地梳理PHP 7及以上版本中那些好用、实用且有趣的内置函数和方法,帮助开发者更好地利用现代PHP的强大功能,编写更简洁、高效的代码。

我们将按照PHP版本升级的顺序,分类介绍各版本中引入的重要函数和方法,并提供实用的代码示例和应用场景。

PHP 7.0 引入的实用函数

1. NULL合并运算符 (??)

NULL合并运算符是PHP 7.0中最受欢迎的特性之一,用于简化三元操作符。

// PHP 7之前的写法
$username = isset($_GET['username']) ? $_GET['username'] : 'guest';

// PHP 7+ 的写法
$username = $_GET['username'] ?? 'guest'; // 如果$_GET['username']存在且不为NULL,则取其值,否则使用'guest'

2. 太空船操作符 (<=>)

太空船操作符用于比较两个表达式,返回-1、0或1。

// 比较数字
echo 1 <=> 1; // 0 (相等)
echo 1 <=> 2; // -1 (左边小于右边)
echo 2 <=> 1; // 1 (左边大于右边)

// 实际应用场景:自定义排序
$users = [
    ['name' => 'John', 'age' => 30],
    ['name' => 'Jane', 'age' => 25],
    ['name' => 'Dave', 'age' => 35]
];

// 按年龄升序排序
usort($users, function ($a, $b) {
    return $a['age'] <=> $b['age'];
});

print_r($users);
// 输出按年龄排序的数组

3. define() 定义数组常量

PHP 7.0允许使用define()定义数组常量,之前只能使用const关键字。

define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]);

echo ANIMALS[1]; // 输出: cat

4. intdiv() 函数

intdiv()用于执行整数除法,返回结果的整数部分。

$result = intdiv(10, 3);
echo $result; // 输出: 3

// 相当于
$result = (int)(10 / 3);

5. random_bytes()random_int()

这两个函数用于生成密码学安全的随机字节和整数,比rand()mt_rand()更安全。

// 生成随机字节
$bytes = random_bytes(16);
echo bin2hex($bytes); // 输出类似: a8e7c6b5d4f3e2c1b0a9d8c7b6a5f4e3

// 生成随机整数
$randomInt = random_int(1, 100);
echo $randomInt; // 输出1到100之间的随机整数

PHP 7.1 引入的实用函数

1. is_iterable() 函数

is_iterable()用于检查变量是否是可迭代的(数组或实现了Traversable接口的对象)。

$arr = [1, 2, 3];
$obj = new ArrayObject([1, 2, 3]);

var_dump(is_iterable($arr)); // bool(true)
var_dump(is_iterable($obj)); // bool(true)
var_dump(is_iterable("hello")); // bool(false)

// 实际应用
function processIterable(iterable $iterable) {
    foreach ($iterable as $value) {
        echo $value . "\n";
    }
}

processIterable($arr); // 正常工作
processIterable($obj); // 正常工作
processIterable("hello"); // 报错: TypeError

2. session_create_id() 函数

session_create_id()用于创建新的会话ID,可用于会话ID的定期更换,提高安全性。

// 开始或恢复会话
session_start();

// 创建新的会话ID
$newSessionId = session_create_id();

// 设置自定义前缀
$customSessionId = session_create_id('myprefix-');
echo $customSessionId; // 输出类似: myprefix-abcdef1234567890

PHP 7.2 引入的实用函数

1. hash_hmac_algos() 函数

hash_hmac_algos()返回适用于hash_hmac的注册算法列表。

$algos = hash_hmac_algos();
print_r($algos);
// 输出所有可用的HMAC算法,如:
// Array
// (
//     [0] => md2
//     [1] => md4
//     [2] => md5
//     [3] => sha1
//     [6] => sha224
//     [7] => sha256
//     [8] => sha384
//     [9] => sha512/224
//     [10] => sha512/256
//     [11] => sha512
//     [12] => sha3-224
//     [13] => sha3-256
//     [14] => sha3-384
//     [15] => sha3-512
//     [16] => ripemd128
//     [17] => ripemd160
//     [18] => ripemd256
//     [19] => ripemd320
//     [20] => whirlpool
//     [21] => tiger128,3
//     [22] => tiger160,3
//     [23] => tiger192,3
//     [24] => tiger128,4
//     [25] => tiger160,4
//     [26] => tiger192,4
//     [27] => snefru
//     [28] => snefru256
//     [29] => gost
//     [30] => gost-crypto
//     [31] => adler32
//     [32] => crc32
//     [33] => crc32b
//     [34] => fnv132
//     [35] => fnv1a32
//     [36] => fnv164
//     [37] => fnv1a64
//     [38] => joaat
//     [39] => haval128,3
//     [40] => haval160,3
//     [41] => haval192,3
//     [42] => haval224,3
//     [43] => haval256,3
//     [44] => haval128,4
//     [45] => haval160,4
//     [46] => haval192,4
//     [47] => haval224,4
//     [48] => haval256,4
//     [49] => haval128,5
//     [50] => haval160,5
//     [51] => haval192,5
//     [52] => haval224,5
//     [53] => haval256,5
// )

PHP 7.3 引入的实用函数

1. is_countable() 函数

is_countable()用于检查变量是否是可计数的(数组或实现了Countable接口的对象)。

$arr = [1, 2, 3];
$obj = new ArrayObject([1, 2, 3]);

var_dump(is_countable($arr)); // bool(true)
var_dump(is_countable($obj)); // bool(true)
var_dump(is_countable("hello")); // bool(false)

// 实际应用
function countItems(countable $countable) {
    return count($countable);
}

echo countItems($arr); // 输出: 3
echo countItems($obj); // 输出: 3
echo countItems("hello"); // 报错: TypeError

2. array_key_first()array_key_last() 函数

这两个函数分别用于获取数组的第一个和最后一个键。

$array = ['a' => 'apple', 'b' => 'banana', 'c' => 'cherry'];

$firstKey = array_key_first($array); // 'a'
$lastKey = array_key_last($array);   // 'c'

echo "第一个元素: " . $array[$firstKey] . "\n"; // apple
echo "最后一个元素: " . $array[$lastKey] . "\n"; // cherry

3. hrtime() 函数

hrtime()用于获取高精度时间,返回由秒和纳秒组成的数组。

// 获取高精度时间
$start = hrtime();

// 执行一些代码
sleep(1);

$end = hrtime();

// 计算执行时间(纳秒)
$elapsedNs = ($end[0] - $start[0]) * 1e9 + ($end[1] - $start[1]);

// 转换为毫秒
$elapsedMs = $elapsedNs / 1e6;

echo "执行时间: " . $elapsedMs . " 毫秒\n";

PHP 7.4 引入的实用函数

1. NULL合并赋值运算符 (??=)

NULL合并赋值运算符是NULL合并运算符的简写形式。

// 原来的写法
$username = $username ?? 'guest';

// 使用NULL合并赋值运算符
$username ??= 'guest'; // 如果$username为NULL,则赋值为'guest'

2. get_mangled_object_vars() 函数

get_mangled_object_vars()返回对象的属性数组,包括无法从外部访问的属性。

class User {
    private $id = 1;
    protected $name = 'John';
    public $email = 'john@example.com';
}

$user = new User();
$vars = get_mangled_object_vars($user);

print_r($vars);
// 输出:
// Array
// (
//     [Userid] => 1
//     [*name] => John
//     [email] => john@example.com
// )

PHP 8.0 引入的实用函数

1. str_contains() 函数

str_contains()用于判断字符串是否包含子字符串,比strpos()更直观。

$haystack = "Hello, world!";
$needle = "world";

// PHP 8之前的写法
if (strpos($haystack, $needle) !== false) {
    echo "包含子字符串\n";
}

// PHP 8+ 的写法
if (str_contains($haystack, $needle)) {
    echo "包含子字符串\n";
}

2. str_starts_with()str_ends_with() 函数

这两个函数分别用于判断字符串是否以指定子字符串开头或结尾。

$filename = "document.pdf";

// 检查文件扩展名
if (str_ends_with($filename, '.pdf')) {
    echo "这是一个PDF文件\n";
}

// 检查URL协议
$url = "https://example.com";
if (str_starts_with($url, 'https://')) {
    echo "这是一个安全的HTTPS链接\n";
}

3. get_debug_type() 函数

get_debug_type()获取变量的类型,与gettype()类似但返回更精确的类型信息。

class User {}
$user = new User();

echo gettype($user);       // 输出: object
echo get_debug_type($user); // 输出: User

echo gettype(10);          // 输出: integer
echo get_debug_type(10);   // 输出: int

4. preg_last_error_msg() 函数

preg_last_error_msg()返回最后一个PCRE正则表达式错误的错误消息,比preg_last_error()更直观。

// 错误的正则表达式
@preg_match('/invalid[regex', 'test string');

// PHP 8之前的写法
$errorCode = preg_last_error();
echo "错误代码: " . $errorCode . "\n";

// PHP 8+ 的写法
$errorMessage = preg_last_error_msg();
echo "错误信息: " . $errorMessage . "\n"; // 输出: Internal error

PHP 8.1 引入的实用函数

1. array_is_list() 函数

array_is_list()判断数组是否是列表(即键是从0开始的连续整数)。

$list1 = [1, 2, 3];
$list2 = ['a' => 1, 'b' => 2, 'c' => 3];
$list3 = [0 => 'a', 1 => 'b', 2 => 'c'];
$list4 = [0 => 'a', 2 => 'b', 3 => 'c'];

var_dump(array_is_list($list1)); // bool(true)
var_dump(array_is_list($list2)); // bool(false)
var_dump(array_is_list($list3)); // bool(true)
var_dump(array_is_list($list4)); // bool(false) (键不连续)

难点用法讲解

1. 太空船操作符的高级用法

太空船操作符不仅可以用于简单值的比较,还可以用于复杂对象的比较,特别是在自定义排序场景中非常有用。

class Product {
    public $name;
    public $price;
    public $sales;
    
    public function __construct($name, $price, $sales) {
        $this->name = $name;
        $this->price = $price;
        $this->sales = $sales;
    }
}

$products = [
    new Product('Laptop', 1200, 150),
    new Product('Phone', 800, 300),
    new Product('Tablet', 500, 200)
];

// 先按销量降序,销量相同则按价格升序
usort($products, function ($a, $b) {
    if ($a->sales !== $b->sales) {
        return $b->sales <=> $a->sales; // 销量降序
    }
    return $a->price <=> $b->price; // 价格升序
});

foreach ($products as $product) {
    echo "产品: {$product->name}, 价格: {$product->price}, 销量: {$product->sales}\n";
}

2. 使用 hrtime() 进行精确的性能分析

hrtime() 可以用于精确测量代码执行时间,特别适用于性能调优。

function benchmark(callable $func, $iterations = 1000) {
    $start = hrtime();
    
    for ($i = 0; $i < $iterations; $i++) {
        $func();
    }
    
    $end = hrtime();
    $elapsedNs = ($end[0] - $start[0]) * 1e9 + ($end[1] - $start[1]);
    $elapsedMs = $elapsedNs / 1e6;
    
    return [
        'total_ms' => $elapsedMs,
        'average_ms' => $elapsedMs / $iterations,
        'iterations' => $iterations
    ];
}

// 测试数组排序性能
$result = benchmark(function() {
    $arr = range(1, 1000);
    shuffle($arr);
    sort($arr);
}, 1000);

echo "总执行时间: {$result['total_ms']} 毫秒\n";
echo "平均执行时间: {$result['average_ms']} 毫秒\n";
echo "迭代次数: {$result['iterations']}\n";

3. 使用 random_bytes()random_int() 提高安全性

random_bytes()random_int() 是密码学安全的随机数生成函数,适用于安全敏感场景。

// 生成安全的API密钥
function generateApiKey($length = 32) {
    return bin2hex(random_bytes($length / 2));
}

$apiKey = generateApiKey();
echo "API密钥: " . $apiKey . "\n";

// 生成一次性令牌
function generateToken() {
    return bin2hex(random_bytes(16)) . '-' . time();
}

$token = generateToken();
echo "一次性令牌: " . $token . "\n";

// 生成安全的验证码
function generateCaptcha($length = 6) {
    $captcha = '';
    for ($i = 0; $i < $length; $i++) {
        $captcha .= (string)random_int(0, 9);
    }
    return $captcha;
}

$captcha = generateCaptcha();
echo "验证码: " . $captcha . "\n";

4. 使用 array_is_list() 验证JSON数组

在处理JSON数据时,可以使用 array_is_list() 来验证解码后的数组是否是JSON数组(而非对象)。

$jsonArray = '[1, 2, 3]';
$JsonObject = '{"a": 1, "b": 2, "c": 3}';

$decodedArray = json_decode($jsonArray);
$decodedObject = json_decode($JsonObject);

// 注意: json_decode默认将JSON对象解码为PHP stdClass对象
// 需要使用第二个参数 true 来解码为关联数组
$decodedObjectAsArray = json_decode($JsonObject, true);

var_dump(array_is_list($decodedArray));          // bool(true)
var_dump(array_is_list($decodedObjectAsArray));  // bool(false)

// 实际应用: 验证API响应是否为数组格式
function validateJsonArray($jsonString) {
    $data = json_decode($jsonString, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        return false; // 无效的JSON
    }
    return array_is_list($data);
}

var_dump(validateJsonArray($jsonArray));  // bool(true)
var_dump(validateJsonArray($JsonObject)); // bool(false)

总结

PHP 7及以上版本引入了许多实用、高效的内置函数和方法,这些新特性不仅提高了代码的可读性和简洁性,还增强了安全性和性能。通过合理使用这些函数,我们可以:

  1. 简化常见操作,减少代码量
  2. 提高代码执行效率
  3. 增强应用程序的安全性
  4. 提高代码的可维护性

作为现代PHP开发者,我们应该积极学习和应用这些新特性,不断更新自己的知识库,编写更加优雅、高效的PHP代码。希望本文介绍的函数和方法能对你的日常开发工作有所帮助。

相关文章

一些编程语言学习心得

作为一名专注于PHP、Go、Java和前端开发(JavaScript、HTML、CSS)的开发者,还得会运维、会谈客户....不想了,都是泪,今天说说这些年学习编程语言的一些体会,不同编程语言在...

Memcached如何配置分布式使用 并附PHP示例

Memcached是一种高性能的分布式内存对象缓存系统,广泛用于加速动态Web应用程序。通过将数据存储在内存中,Memcached能够显著减少数据库负载,提高应用的响应速度Memcached分布...

使用PHP打造轻量级单文件SQLite数据库管理工具

先声明一下,这是我自己内网使用的一个简单的管理工具,所以安全性方面我肯定是没有测试的~ 如果你要放在公网,请添加相关的权限认证及sql防注入等处理在开发过程中,我们经常需要一个简单易用的数据库管...