背景说明:
如今国内开源可用的docker镜像站越发稀少,很多镜像站关闭或不在提供服务。而搭建一个网站只用到少数的几个容器如nginx、php-fpm、mysql,没必要浪费资源买一台香港服务器去拉取这些镜像。解决办法是使用了目前还算稳定的 毫秒镜像 提供的镜像服务。
在1ms.run上搜索php-fpm容器的最新版本时,发现没有官方版本,于是使用了bitnami开源组织上传的镜像bitnami/php-fpm:latest。
在bitnami提供的php-fpm镜像中,容器使用的是UTC时间,也就是协调世界时(全球时间的基准),但我们使用的CST时区(UTC+8),这里就会出现一个问题:博客的发布时间与我们所处的时区有8小时的差距。因此需要修改php-fpm的默认时区设置。
进入php-fpm容器查看时区设置情况
#创建一个临时容器
docker run -itd --rm docker.1ms.run/bitnami/php-fpm
#进入容器查看时区设置
root@f7f574667670:/app# echo $TZ
root@f7f574667670:/app# date
Thu Mar 6 01:24:24 UTC 2025
#发现容器使用的是UTC时间,且没有设置TZ环境变量
第一个思路,修改compose文件php-fpm容器的环境变量,设置TZ的值为Asia/Shanghai
vim compose.yaml
……
php8.2:
container_name: php8.4
image: docker.1ms.run/bitnami/php-fpm:latest
environment:
- TZ=Asia/Shanghai
volumes:
……
为了方便验证,不用每次都去容器里面进行查看时区情况,让deepseek写了一个简单的php脚本,只要浏览器访问这个脚步就可以得到容器的时区信息。
<?php
// 获取当前时间和时区
$current_time = date('Y-m-d H:i:s'); // 格式化当前时间
$current_timezone = date_default_timezone_get(); // 获取当前时区
// 输出结果
echo "当前时间:$current_time\n";
echo "当前时区:$current_timezone\n";
?>
修改完配置信息,使用浏览器验证时发现php-fpm返回的仍然是UTC时间,问题出在哪里?
再次进入php容器,查看环境变量设置是否生效
root@f7f574667670:/app# echo $TZ
Asia/Shanghai
这里发现我们设置的环境变量是生效了的,但是php-fpm返回的时间却又是UTC的,那么下一步我们就去php的配置文件中查看有没有相关设置。
修改php配置,使时区设置生效
查看php.ini文件时,可以发现如下默认配置项。
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone = UTC
这里可以看到默认的时区设置,以及这个时区设置被用于date函数。因此这里的设置优先级高,可以影响到php中时间类函数获取的值。
#使用php --ini命令可快速获取php配置文件的位置
#查找配置信息中含有timezone字段的配置文件
root@f7f574667670:/app# find / -maxdepth 8 -name '*.conf' -o -name '*.ini' | xargs grep timezone
/opt/bitnami/php/etc/php.ini:; Defines the default timezone used by the date functions
/opt/bitnami/php/etc/php.ini:; https://php.net/date.timezone
/opt/bitnami/php/etc/php.ini:date.timezone = UTC
/opt/bitnami/php/lib/php.ini:; Defines the default timezone used by the date functions
/opt/bitnami/php/lib/php.ini:; https://php.net/date.timezone
/opt/bitnami/php/lib/php.ini:date.timezone = UTC
这里发现在php.ini中有一条生效的配置信息:
date.timezone = UTC
修改这个配置文件,把UTC修改成我们需要的时区。这里需要注意的是,如果直接把UTC改为CST,php会报错。
#直接修改为CST
sed -i /^date\.timezone/s/UTC/CST/ /opt/bitnami/php/lib/php.ini
#让php重新加载配置
kill -USR2 $(pgrep php-fpm)
#查看时区信息
php -r 'echo date_default_timezone_get();'
PHP Warning: PHP Startup: Invalid date.timezone value 'CST', using 'UTC' instead in Unknown on line 0
重新修改配置文件,把CST改为"Asia/Shanghai"
sed -i '/^date\.timezone/s/CST/\"Asia\/Shanghai\"/' /opt/bitnami/php/lib/php.ini
或
sed -i /^date\.timezone/s%CST%\"Asia/Shanghai\"% /opt/bitnami/php/lib/php.ini
#重新加载配置文件
root@f7f574667670:/app# kill -USR2 $(pgrep php-fpm)
root@f7f574667670:/app# php -r 'echo date_default_timezone_get();'
Asia/Shanghairoot@f7f574667670:/app#
root@f7f574667670:/app# php -r "echo date('Y-m-d H:i:s');"
2025-03-06 10:44:58root@f7f574667670:/app#
把php.ini文件拷贝出来,在compose文件中写入映射关系,重启php容器即可。
关于php.ini-production和php.ini-development:
这是php给的两个初始配置的模版,区别如下:
开发环境:追求调试便利性,牺牲部分安全性。
生产环境:追求安全与性能,牺牲调试信息。
始终根据实际需求调整配置,两个模板文件只是起点。
配置项 | php.ini-development | php.ini-production |
---|---|---|
目标场景 | 本地开发、调试环境 | 线上生产环境 |
错误报告 | 显示所有错误(方便调试) | 隐藏错误(避免信息泄露) |
性能优化 | 默认配置,无激进优化 | 启用 opcache 等性能优化 |
日志记录 | 可选开启详细日志 | 强制记录错误到日志文件 |
安全限制 | 较为宽松 | 严格限制(如文件上传、执行权限) |
主要区别项目
参数名称 | development | production | 说明 |
---|---|---|---|
zend.exception_ignore_args | Off | On | 开启后,异常堆栈跟踪中不再显示参数的具体值,仅保留参数的类型和数量 |
zend.exception_string_param_max_len | 15 | 0 | 控制异常堆栈信息中 字符串类型参数的最大显示长度 |
error_reporting | E_ALL | E_ALL & ~E_DEPRECATED | 前面报告所有错误,后面忽略部分警告 |
display_errors | On | Off | 是否直接在页面上显示错误 |
display_startup_errors | On | Off | 是否显示PHP启动过程中发生的错误 |
mysqlnd.collect_memory_statistics | On | Off | 启用或禁用统计 MySQL 操作相关的内存使用数据 |
zend.assertions | 1 | -1 | 启用或禁用断言 |
注:1 断言生效,检查条件并触发错误(如条件不满足)。
0 生成断言代码,但不执行检查(类似注释,无性能损耗)。
-1 不生成断言代码(完全忽略 assert(),性能最优,生产环境推荐)。
断言(Assertion) 是开发阶段用于验证代码逻辑的调试工具
评论 (0)