需设计questions、options、answers三张核心表:questions存题干与type字符串,options存选项及sort_order/is_other,answers存question_id+option_id组合及respondent_hash;动态渲染用模板或json schema,提交统一校验并截断填空;交叉分析通过join+group by+case when实现多维统计并返回标准json。

搭建一个支持自定义题型与数据交叉分析的PHP问卷系统,需从数据库结构设计开始,确保每种题型(单选、多选、矩阵、填空、日期、文件上传等)的选项、逻辑跳转、权重设置都能独立存储并可关联分析,不能把所有题干和答案硬塞进同一张宽表。
设计可扩展的题型数据表结构
创建三张核心表:questions(题干)、options(选项)、answers(用户作答)。questions 表中 type 字段用字符串存储 'radio'、'checkbox'、'matrix'、'text' 等值,而非整数枚举——【后续新增题型无需改表结构,只需扩展type值和对应解析逻辑】。
options 表增加 sort_order INT 和 is_other TINYINT(1),前者控制选项显示顺序,后者标识“其他”类开放输入项;answers 表不存原始文本,而是存 question_id + option_id 组合,填空题和文件题则额外在 answer_text 或 file_path 字段记录。
为支持交叉分析,在 answers 表添加 respondent_hash CHAR(32) 字段,用MD5(用户IP+User-Agent+时间戳)生成唯一但非敏感的受访标识,避免依赖登录态。
实现动态题型渲染与提交验证
方法一:服务端模板驱动
在问卷展示页,根据 $question['type'] 的值 include 对应的 partial 文件:type_radio.php、type_matrix.php。每个 partial 内部用 <input name="q[{$q_id}][o{$opt_id}]"> 格式命名控件,保证 POST 数据天然形成嵌套数组结构。
方法二:JSON Schema + 前端渲染
将题型配置序列化为 JSON 输出到页面,前端用 JS 解析并生成表单;提交前调用 validate() 方法校验必填、矩阵完整性、邮箱格式等——【后端必须重验,前端校验仅提升体验】。
所有提交入口统一走 /api/submit.php,接收 $_POST['q'] 后,循环遍历键名提取 question_id 和 option_id,对每组数据查 questions.type 判断是否允许多选,再写入 answers 表;填空题内容过长时截断至 2000 字符,防止 SQL 报错。
构建交叉分析查询引擎
第一步:确定分析维度
从 URL 参数获取维度字段,例如 ?dim1=age_group&dim2=region,这两个字段必须存在于 users 表或通过问卷中某道题(如“您的年龄段?”)的 answer_text 映射而来。
第二步:生成主查询语句
用 LEFT JOIN 连接 answers 表两次(分别代表 dim1 和 dim2 对应的题目),WHERE 条件过滤有效答卷(status = 'completed'),GROUP BY 分组统计频次。
第三步:处理矩阵题交叉
矩阵题的每个子项(如“对客服态度满意程度”)在 options 表中以 parent_id 关联主矩阵题,查询时需先查出该矩阵所有子项 option_id,再在 answers 表中匹配这些 ID,并用 CASE WHEN 动态生成列别名,避免硬编码列名。
第四步:输出标准化结果集
返回 JSON 格式:{ "headers": ["年龄组", "华东", "华北", "华南"], "rows": [["18-25", 12, 8, 15], ["26-35", 22, 19, 27]] },前端直接渲染热力图或堆叠柱状图。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











