CodeIgniter 验证码需前后端配合、时效控制与存储机制,GD 扩展和绝对路径 img_path/img_url 必须正确配置;推荐数据库存储并限制 3 分钟有效期;中文验证码需自定义类指定 UTF-8 字体;表单验证须集成 callback 校验。

CodeIgniter 项目中实现验证码,不能只调用 create_captcha() 就算完事——它只是图像生成环节,真正的安全防护靠的是前后端配合、时效控制与存储机制。原生辅助函数不自带防重放、不自动清理、不校验会话有效性,直接裸用极易被绕过。
GD 库与图片路径是硬门槛
这两个条件不满足,验证码根本不会显示:
- 确认 PHP 已启用 GD 扩展:运行
extension_loaded('gd')返回 true;Docker 环境需额外安装libgd-dev和php-gd -
img_path必须是服务器绝对路径(如FCPATH . 'captcha/'),目录存在且 Web 进程可写(755 或 777) -
img_url必须是浏览器能直接访问的 URL(如base_url() . 'captcha/'),且必须与img_path映射一致,否则<img>标签 404 - 别把路径写成
application/captcha/——该目录不在 Web 根下,无法通过 HTTP 访问
验证码值不能只存 Session
单纯用 $_SESSION['cap'] = $cap['word'] 存值,存在会话劫持、多服务器共享、无限重用等风险:
- 推荐使用数据库表(如
captcha)存储:word、ip_address、captcha_time(UNIX 时间戳) - 验证时加时间判断:
WHERE word = ? AND captcha_time > UNIX_TIMESTAMP() - 180(限制 3 分钟内有效) - 验证成功后立即
DELETE对应记录,杜绝重放 -
expiration参数只控制图片文件保留时间,不影响业务逻辑时效性——这个逻辑必须自己写
中文验证码需自定义支持
原生 create_captcha() 的 pool 参数不支持中文,填入会乱码或报错:
- 需在
application/libraries/下新建Captcha.php类,继承并重写绘图逻辑 - 指定中文字体路径(如
./fonts/simhei.ttf),确保字体文件可读 - 设置
font_path参数指向该字体,并在生成时手动构造中文字符串(如从数组随机取汉字) - 避免使用 GBK 编码字体,优先选 UTF-8 兼容的 TTF(如 Noto Sans CJK)
表单提交时需联动 Form Validation
验证码字段要纳入 CI 的表单验证流程,不能单独 if 判断:
- 在控制器中添加规则:
$this->form_validation->set_rules('captcha', '验证码', 'required|callback_check_captcha') - 定义回调方法
check_captcha($str),内部执行数据库查询+时效校验+删除操作 - 验证失败时调用
$this->form_validation->set_message('check_captcha', '验证码错误或已过期') - 前端需配合
<?php echo form_error('captcha'); ?>输出错误提示,保持体验一致


















