设置MariaDB全局时区后PHP网页展示的timestamp如何减5小时
网页显示数据库timestamp差5小时的解决方法
核心问题根因
MariaDB 的 timestamp 类型字段固定存储UTC标准时间值,查询返回时会根据当前数据库连接自身的会话时区配置,把存储的UTC值换算成对应时区的时间字符串给客户端。
你之前执行的SET @@time_zone := '-05:00'存在两个明显的作用范围问题:
- 这是临时的全局设置,只对语句执行完成后新建立的数据库连接生效,MariaDB服务重启后该设置会直接失效,不是持久化配置
- 你执行这条语句的终端/数据库客户端,本身是一个独立的数据库连接,这个时区设置根本不会同步给PHP网页新建的数据库连接;PHP侧的连接一直沿用服务器默认的UTC时区,所以查出来的时间会比你客户端看到的数值刚好多了5小时
你在客户端看到数据库表时间显示为2021-03-29 15:53:51,本质是客户端会话把存储的UTC值换算成西五区时间展示了,不是表内存储的原始时间值发生了变化。
可落地的修复方案
方案1(最可靠,不受服务器全局配置影响)
在PHP完成数据库连接初始化后,立刻给当前PHP使用的数据库连接单独设置会话时区,不需要改动MariaDB的核心配置。
在你的config.php文件里,完成数据库连接创建、拿到$link连接对象之后,第一行就加上时区设置代码:
// 给当前PHP使用的数据库连接设置西五区时区 mysqli_query($link, "SET time_zone = '-05:00'");
设置完成后,这个连接下所有timestamp字段的查询结果,都会直接换算成西五区的时间值返回,彻底消除时差。
方案2(一劳永逸)
如果希望所有连接数据库的程序都默认使用西五区时区,可以修改MariaDB的全局配置实现永久生效:
- 打开MariaDB的配置文件
my.cnf,定位到[mysqld]配置段 - 添加时区配置项:
default-time-zone = '-05:00' - 保存配置文件,重启MariaDB服务,后续所有新建的数据库连接都会默认套用这个时区,不需要单独设置。
现有PHP代码的附带修复
你贴出的代码本身存在两处会影响运行的漏洞:
- 判断结果集有数据后,没有调用
mysqli_fetch_assoc()方法逐行取出查询结果,$row变量根本不会被赋值 - 打印时间的语句存在语法错误,
echo . $row['time'] .;无法正常解析运行
修正后的结果读取逻辑如下:
if($result = mysqli_query($link, $sql)){ if(mysqli_num_rows($result) > 0){ // 循环遍历取出每一行数据 while($row = mysqli_fetch_assoc($result)) { // 转义输出避免XSS安全问题 echo htmlspecialchars($row['time']) . "<br>"; } mysqli_free_result($result); } else{ echo "<p class='lead'><em>No records were found.</em></p>"; } } else{ echo "ERROR: Could not able to execute $sql. " . mysqli_error($link); }
内容的提问来源于stack exchange,提问作者Luke To
相关产品推荐
相关产品推荐

