CodeIgniter3本地与Docker服务器环境验证错误消息显示不一致
问题现象
本地Windows环境中,必填字段未填写时,验证错误消息会正确显示字段名(例如:The Username field is required.);但将应用部署到Ubuntu主机的Docker环境后,错误消息仅显示The field is required.,缺失字段名。
已知信息:
- 两个环境均运行PHP 8.3,CodeIgniter版本一致
- 已核对PHP错误报告设置无差异
- 检查
config.php和database.php未发现相关环境配置差异
相关配置与代码
Docker Compose 文件
version: '3' services: db: build: context: . dockerfile: docker/mysql/Dockerfile restart: always environment: MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD} MARIADB_DATABASE: ${MARIADB_DATABASE} volumes: - ./db_data:/usr/data ports: - "3309:3306" web: build: context: . dockerfile: docker/apache/Dockerfile restart: unless-stopped volumes: - .:/var/www/html - ./apache_log:/var/log/apache2 ports: - 84:80 depends_on: - db links: - db adminer: image: adminer restart: unless-stopped ports: - 8084:8080
Dockerfile
# use php 8.3 apache image FROM php:8.3-apache # Update it RUN apt-get update # install necessary libraries RUN apt-get install -y \ git \ zip \ curl \ sudo \ unzip \ libicu-dev \ libbz2-dev \ libpng-dev \ libjpeg-dev \ libmcrypt-dev \ libreadline-dev \ libfreetype6-dev \ g++ # install docker extensions RUN docker-php-ext-install \ bz2 \ intl \ bcmath \ opcache \ calendar \ pdo_mysql \ mysqli # set up document root for apache COPY docker/apache/000-default.conf /etc/apache2/sites-available/000-default.conf # mod_rewrite for URL rewrite and mod_headers for .htaccess extra headers like Access-Control-Allow-Origin- RUN a2enmod rewrite headers # start with base php config, then add extensions RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" # composer RUN curl -sS https://getcomposer.org/installer | php RUN mv composer.phar /usr/local/bin/composer RUN chmod +x /usr/local/bin/composer RUN composer self-update COPY . /var/www/html/ RUN chown -R www-data:www-data /var/www/html && \ chmod -R 755 /var/www/html EXPOSE 80
CodeIgniter 验证控制器代码
$rules = [ 'username' => [ 'rules' => 'required|string|min_length[5]|max_length[30]', 'errors' => [ 'required' => lang('validation.required', ['field' => lang('users.usersInputUsername')]), ], ], ];
排查与解决方案
1. 检查语言文件权限
Docker容器内application/language目录及其子文件的权限可能导致PHP无法读取语言配置。执行以下命令修复权限:
# 进入容器 docker exec -it <web容器名或ID> bash # 修复语言目录及文件权限 chown -R www-data:www-data /var/www/html/application/language chmod -R 755 /var/www/html/application/language chmod 644 /var/www/html/application/language/**/*.php
2. 确认语言配置一致性
检查application/config/config.php中的语言设置,确保两个环境的配置相同:
// 确认语言设置一致,例如: $config['language'] = 'english';
3. 强制加载目标语言文件
在验证逻辑所在的控制器中,手动加载users语言文件,避免自动加载失效:
$this->lang->load('users', $this->config->item('language')); $this->lang->load('validation', $this->config->item('language'));
4. 验证语言函数返回值
在控制器中临时添加调试代码,确认lang('users.usersInputUsername')在Docker环境中能正确返回字段名:
var_dump(lang('users.usersInputUsername')); exit;
如果返回空或错误值,检查application/language/english/users_lang.php中是否存在$lang['usersInputUsername'] = 'Username';的定义。
5. 调整错误消息写法
临时修改错误消息的拼接方式,验证占位符替换是否正常:
'errors' => [ 'required' => 'The ' . lang('users.usersInputUsername') . ' field is required.', ],
如果这样能正常显示字段名,说明原写法中lang('validation.required', [...])的占位符解析存在问题,可进一步检查validation_lang.php中的对应消息定义是否正确:
// 确认validation_lang.php中有正确的占位符 $lang['required'] = 'The {field} field is required.';
6. 清除缓存
CodeIgniter的缓存可能导致语言文件未更新,清除application/cache目录下的所有文件:
rm -rf /var/www/html/application/cache/*
内容的提问来源于stack exchange,提问作者Shamith Wimukthi

