0

0

PHP 8.1 升级指南:告别 each() 与解决 mktime() 类型错误

DDD

DDD

发布时间:2025-12-03 13:01:20

|

904人浏览过

|

来源于php中文网

原创

php 8.1 升级指南:告别 each() 与解决 mktime() 类型错误

本文旨在指导开发者如何将旧版PHP代码中的 `each()` 函数安全地迁移到 `foreach()` 结构,并重点解决在PHP 8.1环境下常见的 `mktime()` 函数因类型不匹配导致的 `TypeError`。我们将详细解释 `explode()` 返回字符串数组与 `mktime()` 期望整型参数之间的冲突,并提供使用显式类型转换 `(int)` 的解决方案,确保代码在现代PHP版本中稳定运行。

PHP 8.1 升级:从 each() 到 foreach() 的迁移与常见类型错误解析

随着PHP版本的不断演进,一些旧有的函数和语法已被废弃或移除,以提升语言的性能、安全性和一致性。其中,each() 函数在PHP 7.2中被废弃,并在PHP 8.0中彻底移除。因此,对于需要将旧项目升级到PHP 8.1或更高版本的开发者而言,将代码中的 each() 替换为 foreach() 循环是必不可少的一步。

1. each() 函数的废弃与 foreach() 的替代

在旧版PHP中,each() 函数常与 while 循环结合使用,用于遍历数组,每次迭代返回当前元素的键值对。其典型用法如下:

while (list($key, $value) = each($array)) {
    // 处理 $key 和 $value
}

然而,each() 存在性能和语义上的局限性,并且随着PHP语言的发展,更简洁、高效的 foreach() 循环成为了遍历数组的首选方式。foreach() 循环直接提供了对数组键和值的访问,无需额外的函数调用,代码可读性更强。

立即学习PHP免费学习笔记(深入)”;

将上述 each() 循环转换为 foreach() 的正确方式是:

foreach ($array as $key => $value) {
    // 处理 $key 和 $value
}

注意事项: 在进行 each() 到 foreach() 的转换时,如果原始数组 $array 存在为空或非数组的可能,为了避免PHP 8.1中可能出现的 TypeError(当 foreach 尝试遍历非数组或不可遍历的值时),建议在 foreach 之前进行类型检查或强制转换为数组。例如:

// 原始代码片段
// while (list($uhrzeit, $value) = each($wrdata)) { ... }

// 转换为 foreach 并进行类型安全处理
foreach ((array) $wrdata as $uhrzeit => $value) {
    // ... 循环体内容
}

通过 (array) $wrdata 强制类型转换,即使 $wrdata 为 null 或其他非数组类型,也会被安全地转换为一个空数组,从而避免 foreach 报错。

2. 解决 mktime() 函数的 TypeError

在将代码从PHP 7.4升级到PHP 8.1时,仅仅替换 each() 可能不足以解决所有问题。一个常见的错误是 mktime() 函数引发的 TypeError,提示其参数必须是 int 类型,但实际接收到了 string 类型。

错误示例:

A1.art
A1.art

一个创新的AI艺术应用平台,旨在简化和普及艺术创作

下载
Fatal error: Uncaught TypeError: mktime(): Argument #1 ($hour) must be of type int, string given in /path/to/your/file.php:106
Stack trace: #0 /path/to/your/file.php(106): mktime('', NULL, NULL, '12', '08', '10') #1 ...

这个错误信息清晰地表明,mktime() 函数的第一个参数($hour)期望一个整数,但实际传入了一个字符串。结合原始代码,问题通常出现在时间字符串的解析和使用上:

$time_split = explode(":", $uhrzeit);
$timestamp = mktime ($time_split[0], $time_split[1], $time_split[2], $month, $day, $year );

这里的 $uhrzeit 通常是一个时间字符串(例如 "10:30:00")。explode(":", $uhrzeit) 函数会将其分割成一个字符串数组,例如 ['10', '30', '00']。在旧版PHP中,字符串在某些上下文中会被隐式地转换为数字,但PHP 8.1 对类型检查更为严格,不再允许这种隐式转换,因此 mktime() 会抛出 TypeError。

解决方案:显式类型转换

解决此问题的方法是使用显式类型转换,确保传递给 mktime() 的参数都是整数类型。可以通过在变量前加上 (int) 来实现。

$time_split = explode(":", $uhrzeit);
$timestamp = mktime(
    (int)$time_split[0], // 强制转换为整数:小时
    (int)$time_split[1], // 强制转换为整数:分钟
    (int)$time_split[2], // 强制转换为整数:秒
    $month,
    $day,
    $year
);

通过 (int)$time_split[0] 等操作,我们将 explode() 返回的字符串数组元素显式地转换成了整数,从而满足了 mktime() 函数的参数类型要求。

为什么需要显式转换?explode() 函数根据分隔符将字符串拆分为一个字符串数组。例如,explode(":", "10:30:45") 将返回 ['10', '30', '45'],其中的 '10'、'30'、'45' 都是字符串类型。而 mktime() 函数,顾名思义,是用于创建Unix时间戳的,其小时、分钟、秒等参数都必须是整数。PHP 8.1 强化了类型严格性,不再容忍这种潜在的类型不匹配,因此需要开发者手动进行类型转换。

3. 升级过程中的其他注意事项

在进行PHP版本升级时,特别是从旧版本(如PHP 7.x)升级到PHP 8.x,可能会遇到更多类似的类型错误或其他兼容性问题。

  • 阅读官方迁移指南: PHP官方提供了详细的迁移指南(例如 PHP 8.1 迁移指南),其中列举了所有向后不兼容的变更、废弃的功能和新增的特性。这是解决升级问题的最佳起点。
  • 关注错误日志: PHP 8.1 的错误报告更为详细和准确。仔细阅读 Warning、Error 和 Fatal error 信息,它们通常会直接指出问题所在,包括文件名、行号以及期望的类型与实际接收到的类型。
  • 逐步升级与测试: 建议不要一次性升级所有代码。可以考虑在开发环境中逐步修复问题,并进行全面的单元测试和集成测试,确保所有功能在新的PHP版本下都能正常运行。
  • 使用静态分析工具 PHPStan、Psalm 等静态分析工具可以在代码运行前发现潜在的类型错误、废弃函数使用等问题,为升级提供有力帮助。

总结

将旧版PHP代码迁移到PHP 8.1及更高版本,主要涉及到对废弃功能的替换(如 each() 到 foreach())以及对类型严格性增强的适应(如 mktime() 参数的显式类型转换)。理解这些变化背后的原因,并遵循官方指南和最佳实践,将有助于开发者顺利完成代码升级,使应用程序在现代PHP环境中更加健壮和高效。始终记住,详细的错误信息是解决问题的关键线索,而显式类型转换则是应对PHP 8.1严格类型检查的有效策略。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1010

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1089

2024.03.01

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

106

2023.09.25

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

266

2025.12.04

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

492

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

382

2023.10.25

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 13.3万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号