PHP评论系统提交空白页 表单与验证码验证失效问题排查
问题根因排查
- 空白页核心诱因:所有依赖Session的页面(评论表单页、提交处理页)未添加
session_start(),验证码存储在Session中无法正常读取;所有header()跳转后未加exit;终止代码执行,逻辑穿透触发运行异常。 - 校验逻辑缺陷:原有空值校验为合并判断,无法单独返回对应字段的定制提示;验证码校验未覆盖空输入场景,未做大小写兼容处理。
- 代码逻辑漏洞:SQL语句直接拼接参数存在注入风险;评分字段未做默认值/范围校验,用户未选评分时传入空值触发数据库报错;验证码生成逻辑中Session赋值放在图片输出之后,HTTP头已发送无法写入Session,验证码永久失效。
- 路径匹配错误:表单提交后跳转地址写为
indexcomment.php,但实际表单页文件名为comments.php,路径不匹配触发404/空白页。
修复步骤&对应代码
1. 修复captcha.php验证码存储逻辑
将验证码存入Session的操作移到所有输出之前,新增大小写兼容处理:
<?php session_start(); $image_width = 280; $image_height = 40; $characters_on_image = 6; $font = './fonts/monofont.ttf'; $possible_letters = '23456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ'; $random_dots = 30; $random_lines = 20; $captcha_text_color="0x142864"; $captcha_noice_color = "0x142864"; $code = ''; $i = 0; while ($i < $characters_on_image) { $code .= substr($possible_letters, mt_rand(0, strlen($possible_letters)-1), 1); $i++; } // 提前存储验证码,禁止放在图片输出之后 $_SESSION['6_letters_code'] = strtolower($code); $font_size = $image_height * .75; $image = @imagecreate($image_width, $image_height); $background_color = imagecolorallocate($image, 255, 255, 255); $arr_text_color = hexrgb($captcha_text_color); $text_color = imagecolorallocate($image, $arr_text_color['red'], $arr_text_color['green'], $arr_text_color['blue']); $arr_noice_color = hexrgb($captcha_noice_color); $image_noise_color = imagecolorallocate($image, $arr_noice_color['red'], $arr_noice_color['green'], $arr_noice_color['blue']); for( $i=0; $i<$random_dots; $i++ ) { imagefilledellipse($image, mt_rand(0,$image_width), mt_rand(0,$image_height), 2, 3, $image_noise_color); } for( $i=0; $i<$random_lines; $i++ ) { imageline($image, mt_rand(0,$image_width), mt_rand(0,$image_height), mt_rand(0,$image_width), mt_rand(0,$image_height), $image_noise_color); } $textbox = imagettfbbox($font_size, 0, $font, $code); $x = ($image_width - $textbox[4])/2; $y = ($image_height - $textbox[5])/2; imagettftext($image, $font_size, 0, $x, $y, $text_color, $font , $code); header('Content-Type: image/jpeg'); imagejpeg($image); imagedestroy($image); function hexrgb ($hexstr) { $int = hexdec($hexstr); return array("red" => 0xFF & ($int >> 0x10), "green" => 0xFF & ($int >> 0x8), "blue" => 0xFF & $int); } ?>
2. 修复post_comment.php提交处理逻辑
文件开头开启Session,拆分校验规则匹配定制提示,所有跳转后加终止逻辑,参数做基础过滤:
<?php session_start(); include_once 'controllers/Comment.php'; $com = new Comment(); if (isset($_POST['submit'])) { // 接收参数并做首尾去空、类型转换处理 $name = trim($_POST['name'] ?? ''); $comment = trim($_POST['comment'] ?? ''); $rating = intval($_POST['rating'] ?? 0); $captcha = trim($_POST['6_letters_code'] ?? ''); // 逐字段校验,返回对应提示 if(empty($_SESSION['6_letters_code']) || empty($captcha) || strtolower($_SESSION['6_letters_code']) != strtolower($captcha)) { header('Location: comments.php?msg='.urlencode('Security code is invalid')); exit; } if (empty($name)) { header('Location: comments.php?msg='.urlencode('Name should not be empty')); exit; } if (empty($comment)) { header('Location: comments.php?msg='.urlencode('Text should not be empty')); exit; } if ($rating <1 || $rating>5) { header('Location: comments.php?msg='.urlencode('Please select a rating')); exit; } // 校验通过清除验证码,防止重复提交 unset($_SESSION['6_letters_code']); $com->setData($name, $comment, $rating); if ($com->create()) { header('Location: comments.php?msg='.urlencode('Comment Posting Successfully')); exit; } else { header('Location: comments.php?msg='.urlencode('Failed to post comment, please try again')); exit; } } // 非提交请求直接跳回评论页 header('Location: comments.php'); exit; ?>
3. 修复Comment.php模型SQL注入风险
改用mysqli预处理语句,禁止直接拼接用户输入参数到SQL语句:
<?php include_once './database/DB.php'; class Comment { private $db; private $name; private $comment; private $rating; private $table = "tbl_comments"; public function __construct() { $this->db = new DB(); } public function setData($name, $comment, $rating) { $this->name = $name; $this->comment = $comment; $this->rating = $rating; } public function create() { // 预处理SQL防注入 $stmt = $this->db->link->prepare("INSERT INTO $this->table(name, comment, rating, comment_time) VALUES(?, ?, ?, now())"); $stmt->bind_param("ssi", $this->name, $this->comment, $this->rating); $result = $stmt->execute(); $stmt->close(); return $result; } public function index() { $query = "SELECT * FROM $this->table ORDER BY id DESC"; $result = $this->db->select($query); return $result; } public function dateFormat($data) { date_default_timezone_set('Europe/Berlin'); $date = date('M j, Y', time()); return $date; } } ?>
4. 修复comments.php页面依赖
在文件最开头(所有HTML输出之前)添加<?php session_start(); ?>,确保Session可正常读取;可给5星评分单选框加checked属性,避免用户漏选评分。
额外排查建议
- 确认项目内文件相对路径正确,include引入文件路径错误也会触发空白页,可在php.ini中开启
display_errors = On、error_reporting = E_ALL直接输出错误信息定位问题。 - 确认
fonts/monofont.ttf字体文件存在,字体缺失会导致验证码生成失败。
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

