[我的原创文章] 多页多项可单选可复选调查的实现

发表于:2007-05-25来源:作者:点击数: 标签:原创文章多页多项单选我的
现在有一个小的项目(已经实现),做一个产品调查,限于某些原因,以下所给出的内容会有所删节。 基本要求: 1、问题分为几个大类 2、每个大类之中包含若干个问题 3、每个问题可能是多选,也可能是单选 4、有的问题,可以输入文字 [size=20:9b79c6637a][co

现在有一个小的项目(已经实现),做一个产品调查,限于某些原因,以下所给出的内容会有所删节。

基本要求:
1、问题分为几个大类
2、每个大类之中包含若干个问题
3、每个问题可能是多选,也可能是单选
4、有的问题,可以输入文字

[size=20:9b79c6637a][color=red:9b79c6637a]本文所揭示的:
如何取得某个被调查者的每个问题的结果。[/color:9b79c6637a]
[/size:9b79c6637a]

当然:要是按照普通的方法,也可以发扬愚公移山的精神为每一个问题设置一个选项的名字,然后再PHP之中依次取得其值。

但是:我们要使用更好的方法来取得其值!!!

 HonestQiao 回复于:2005-04-15 17:02:28
问题页面设计:第一问题分类页面:
[code:1:ee17087108]
<PRE>
<form action="invest.php" method="post" target="_self">
一、第一类问题
1. 问题1?
<input type="checkbox" name="q1[1][]" value="1">选项1
<input type="checkbox" name="q1[1][]" value="2">选项2

2. 问题2?
<input type="radio" name="q1[2][]" value="1">选项1
<input type="radio" name="q1[2][]" value="2">选项2
<input type="text"  name="q1_input[2]" value="">


<input name="step" type="hidden" id="step" value="1">
<input type="submit" name="Submit" value="下一步">
</form>
</PRE>
[/code:1:ee17087108]

 HonestQiao 回复于:2005-04-15 17:07:07
问题页面设计:第二问题分类页面:
[code:1:06639d1d6d]
<PRE>
<form action="invest.php" method="post" target="_self">
二、第二类问题
1. 问题1?
<input type="checkbox" name="q2[1][]" value="1">选项1
<input type="checkbox" name="q2[1][]" value="2">选项2

2. 问题2?
<input type="radio" name="q2[2][]" value="1">选项1
<input type="radio" name="q2[2][]" value="2">选项2
<input type="text"  name="q2_input[2]" value="">


<input name="step" type="hidden" id="step" value="2">
<input type="submit" name="Submit" value="下一步">
</form>
</PRE>
[/code:1:06639d1d6d]

 HonestQiao 回复于:2005-04-15 17:12:02
问题页面设计:第三问题分类页面:
[code:1:1e201a60a2]
<PRE>
<form action="invest.php" method="post" target="_self">
三、第三类问题
1. 问题1?
<input type="checkbox" name="q3[1][]" value="1">选项1
<input type="checkbox" name="q3[1][]" value="2">选项2

2. 问题2?
<input type="radio" name="q3[2][]" value="1">选项1
<input type="radio" name="q3[2][]" value="2">选项2
<input type="text"  name="q3_input[2]" value="">


<input name="step" type="hidden" id="step" value="3">
<input type="submit" name="Submit" value="下一步">
</form>
</PRE>
[/code:1:1e201a60a2]

 HonestQiao 回复于:2005-04-15 17:18:39
问题页面设计:选项的设计技巧:

从以上三个问题页面的HTML代码可以看出:
[code:1:b6efb7b6e4]
<input type="radio" name="q1[2][]" value="2">
[/code:1:b6efb7b6e4]
[color=red:b6efb7b6e4]
q1、q2、q3表示问题的分类
q1[2]表示这是第一个分类的第二个问题
q1[2][]表示这是第一个分类的第二个问题的选项
value="2" 表示这是第二个选项
[/color:b6efb7b6e4]

[code:1:b6efb7b6e4]
<input name="step" type="hidden" id="step" value="1">
[/code:1:b6efb7b6e4]

这个表示进行到了第几个问题分类

 HonestQiao 回复于:2005-04-15 17:33:25
特别注意:以下程序经过删节,如有不全之处,请告知
[code:1:clearcase/" target="_blank" >cc1332e52c]
<?php

session_start();
$intStep=(int)$_POST['step'];
if ($intStep==0)
{
    session_unset();
    session_destroy();
    session_register("invest_setp");
    $_SESSION["invest_setp"] = 1;
    include("q1.htm");
}
else if ($intStep==1 && $_SESSION["invest_setp"]==1)
{
    session_register("INVEST_ANSWER_1");
    $_SESSION["INVEST_ANSWER_1"] = $_POST["q1"];
    session_register("INVEST_INPUT_1");
    $_SESSION["INVEST_INPUT_1"] = $_POST["q1_input"];

    include("q2.htm");
}
else if ($intStep==2 && $_SESSION["invest_setp"]==1)
{
    session_register("INVEST_ANSWER_2");
    $_SESSION["INVEST_ANSWER_2"] = $_POST["q2"];
    session_register("INVEST_INPUT_2");
    $_SESSION["INVEST_INPUT_2"] = $_POST["q2_input"];

    include("q3.htm");
}
else if ($intStep==3 && $_SESSION["invest_setp"]==1)
{
     session_register("INVEST_ANSWER_3");
     $_SESSION["INVEST_ANSWER_3"] = $_POST["q3"];
     session_register("INVEST_INPUT_3");
     $_SESSION["INVEST_INPUT_3"] = $_POST["q3_input"];

    session_register("INVEST_USER");
    $_SESSION["INVEST_USER"] = $_POST["u_input"];

    $intUID = 0;

    /// 调查表格
    $strSQLSelect = "";
    $strSQLInput = "";

    for ($intQCID = 1;$intQCID<=3;$intQCID++)
    {
        $strSESSION_QNAME = "INVEST_ANSWER_$intQCID";
        $strSESSION_QINPUT = "INVEST_INPUT_$intQCID";
    
        $intCount = count($_SESSION["$strSESSION_QNAME"]);
        for ($i=1;$i<=$intCount;$i++)
        {
            $intQID = $i;
            $intCountJ = count($_SESSION["$strSESSION_QNAME"][$i]);
            for ($j=0;$j<$intCountJ;$j++)
            {
                $intSID = (int)$_SESSION["$strSESSION_QNAME"][$i][$j];
                $intSVALUE = 1;
                if ($strSQLSelect!="") $strSQLSelect.=",";
                $strSQLSelect .= "
                ($intUID, $intQCID, $intQID, $intSID, $intSVALUE)
                ";
            }
        
            $strSINPUT = addslashes($_SESSION["$strSESSION_QINPUT"][$i]);
            $intSID = 0;
            if ($strSINPUT!="" || !empty($strSINPUT))
            {
               if ($strSQLInput!="") $strSQLInput .= ",";
               $strSQLInput.= "
                   ($intUID, $intQCID, $intQID, $intSID, '$strSINPUT')
               ";
            }
        }
    }
}
else
{
    session_unset();
    session_destroy();
    session_register("invest_setp");
    $_SESSION["invest_setp"] = 1;
    include("q1.htm");
}
?>
[/code:1:cc1332e52c]

 HonestQiao 回复于:2005-04-15 17:39:48
[code:1:392a0f1788]
    session_register("INVEST_ANSWER_1"); 
    $_SESSION["INVEST_ANSWER_1"] = $_POST["q1"]; 
[/code:1:392a0f1788]

这个表示,使用SESSION来缓存第一个问题分类的用户提交数据。
当然你可以采取其他方法,在这里,我们演示为SESSION

[code:1:392a0f1788]
   session_register("INVEST_INPUT_1"); 
   $_SESSION["INVEST_INPUT_1"] = $_POST["q1_input"]; 
[/code:1:392a0f1788]
这个表示缓存用户输入

[code:1:392a0f1788]
  for ($intQCID = 1;$intQCID<=3;$intQCID++) 
[/code:1:392a0f1788]
这个表示当前问题,有三个大的分类

[code:1:392a0f1788]
       $strSESSION_QNAME = "INVEST_ANSWER_$intQCID"; 
       $strSESSION_QINPUT = "INVEST_INPUT_$intQCID"; 
[/code:1:392a0f1788]
这个表示获取某个大的问题的分类的SESSION保存名称

[code:1:392a0f1788]
       $intCount = count($_SESSION["$strSESSION_QNAME"]); 
       for ($i=1;$i<=$intCount;$i++) 
[/code:1:392a0f1788]
  这个表示该分类有多少个问题,并进行循环

[code:1:392a0f1788]
           $intCountJ = count($_SESSION["$strSESSION_QNAME"][$i]); 
 for ($j=0;$j<$intCountJ;$j++) 
[/code:1:392a0f1788]
    这个表示当前问题,已经选择的选项,并进行循环

[code:1:392a0f1788]
$intSID = (int)$_SESSION["$strSESSION_QNAME"][$i][$j]; 
[/code:1:392a0f1788]
这个表示获取选项值

[code:1:392a0f1788]
$strSINPUT = addslashes($_SESSION["$strSESSION_QINPUT"][$i]); 
[/code:1:392a0f1788]
这个表示获取该问题用户输入的文字

 HonestQiao 回复于:2005-04-15 17:54:08
HTML之中选项命名规则:
QM[N][]
Q:表示问题,常量字符
M:表示问题分类,整数
[N]:表示当前分类的第几个问题,[整数]
[]:表示属于该问题的一个选项

PHP之中如何取得选项的值呢?
在提交表单之后,如果input输入项的名字相同,会自动形成一个数组传递给你的PHP程序

首先,QM确定了该问题的分类,而QM本身就成为了一个问题的结果的数组。
然后,[N],表示了是QM分类的第几个问题,而我们恰好通过这个N,到QM数组取得对应的选项数据。
然后,[],我们没有设定其值,但是,我们选择了之后,他会自动生成一个选项值的数组,因而我们可以获取这个数组的大小,得到选项的数目;如果是单选,大小为1,如果不是,根据实际的大小得知多选的个数。
然后,[],之中,我们在HTML设置了每一个选项的值分别为1,2,......

因而,通过QM我们得知了该分类,有多少个问题
通过QM[N],我们得知了是哪一个问题,并且得知用户选择了几个选项
通过遍历QM[N],我们得知了用户选择了那几个选项。

因而,我们通过一个巧妙的构造输入选项的名称,从而在PHP之中可以简单有效的获取用户的输入结果。

随后的一点提示:
如果要保存到数据库,那么你可以这么做:
ID UID QCID QID SID SVALE
ID: 自动增加的编号
UID:用户的编号,你可能需要
QCID:分类编号
QID:问题编号
SID:选项编号
SVALE:选项的值或者设置为1表示选择了这个选项

 yb0312 回复于:2005-04-15 17:55:38
谢谢!正在找这类文章,不过我想问一下,满屏幕都是session.为什么不用cookie当数组存起来呢?

 HonestQiao 回复于:2005-04-15 18:05:17
[quote:7a5d988bae="yb0312"]谢谢!正在找这类文章,不过我想问一下,满屏幕都是session.为什么不用cookie当数组存起来呢?[/quote:7a5d988bae]

我说了:
[quote:7a5d988bae="HonestQiao大大"]
这个表示,使用SESSION来缓存第一个问题分类的用户提交数据。 
当然你可以采取其他方法,在这里,我们演示为SESSION [/quote:7a5d988bae]

 geel 回复于:2005-04-16 02:16:49
这个问题3年前我用asp实现了一把 :)

 HonestQiao 回复于:2005-04-16 10:12:23
但是你没有共享出来,所以大家好事需要的,虽然对于你来说是陈旧的小儿科的

 imbiss 回复于:2005-04-16 19:55:33
为了填一个调查表,要在客户和服务器之间来回那么多回合。能不能这样。

把所有问题全部坐在一个html里面。
每一类的问题放在不同的层。
通过js来显示或隐藏层,来适应用户的选择。

通过最后一个按钮,把数据一次发送到服务器服务器遍历所有数据,添加到数据库。

这样做的优点
1.用户觉得相应快速。因为是本地js实现,用户不必等待
2.万一用户中途放弃填写,不会在服务器上产生垃圾数据。

缺点
客户需要打开js。

 HonestQiao 回复于:2005-04-16 23:07:18
所以还是分页面的按部就班的好。
用JS,不同的浏览器支持不同,不同的操作系统可能差别很大。
还有,N多都禁止了运行,例如很多浏览器,默认的瘟到死SP2下面的浏览器

 imbiss 回复于:2005-04-16 23:31:51
[quote:b700dfb133="HonestQiao"]所以还是分页面的按部就班的好。
用JS,不同的浏览器支持不同,不同的操作系统可能差别很大。
还有,N多都禁止了运行,例如很多浏览器,默认的瘟到死SP2下面的浏览器[/quote:b700dfb133]
那你如何处理用户中途放弃的数据呢?
比如一共10页,用户填了5页就没耐性了,走了。可是部分数据已经提交到数据库了,怎么办?
添加一个是否有效的字段?
 :lol:

 HonestQiao 回复于:2005-04-17 23:48:38
[quote:26937b7316="imbiss"]
那你如何处理用户中途放弃的数据呢?
比如一共10页,用户填了5页就没耐性了,走了。可是部分数据已经提交到数据库了,怎么办?
添加一个是否有效的字段?
 :lol:[/quote:26937b7316]

大哥,拜托你看贴再回帖喔。

我们是在用户所有的调查完成了之后,才录入数据库的。

我不知道我们中途那一步将数据放入了数据库呢?
还望指点。

 imbiss 回复于:2005-04-17 23:55:44
就是说,在用户没完成最后一步之前,数据都保存在session里面了,对吗?

 HonestQiao 回复于:2005-04-17 23:58:49
[quote:b312b35759="imbiss"]就是说,在用户没完成最后一步之前,数据都保存在session里面了,对吗?[/quote:b312b35759]

我们只是举例子:
可以SESSION:如果用户中途离开了,SESSION可以自动的清除数据的
也可以COOKIE:如果用户中途离开了,呵呵,与我们服务器无关
还可以是序列化之后,使用FORM的Hidden的Input来表示:同上

 imbiss 回复于:2005-04-18 02:57:22
要是我做的话,思路如下
数据库
表a, 问卷表
记录所有问题,每一个问题对应一行记录

表b,答卷表
记录所有答卷
每个记录对应一张答卷。
前面记录调查者的信息,后面对应问卷表的每个问题有每个记录。因为只是选择题,所以不选为NULL,选中为true. 最后加一个是否有效的列。

前台部分
调查表用js作,分层显示。最后提一次提交数据库,返回结果,感谢信息,game over.

 HonestQiao 回复于:2005-04-18 11:06:20
大哥,I服了you,大哥你怎么老跑题啊?

前面的帖子,你自己回复的包括其他任何我回复的,希望可以看一看哦。

这个帖子主要说的是,如何能更好的取得结果。

而你所说的,对于这个帖子的主旨来说,似乎完全跑题了。

而你所说的什问卷表么、答卷表、什么前台部分,这些,哎,我不作评价了。

 geel 回复于:2005-04-18 11:24:22
[quote:a064ca790f="HonestQiao"]但是你没有共享出来,所以大家好事需要的,虽然对于你来说是陈旧的小儿科的[/quote:a064ca790f]

我以为很简单,拿出来会被人笑话,就没敢 :oops:

 HonestQiao 回复于:2005-04-18 12:09:28
[quote:219e6cd999="geel"]

我以为很简单,拿出来会被人笑话,就没敢 :oops:[/quote:219e6cd999]

哦,我很受打击的,你这么说。

管它哪,这年头,好酒也怕巷子深;要是大家喜欢的话,也可以成为好酒

 imbiss 回复于:2005-04-18 15:47:26
:lol: 
抱歉跑题了。
你的代码大致看了一下。我
不知道你说的作的更好是指什么,或者说哪方面能做的更好?
 :mrgreen:

 geel 回复于:2005-04-18 16:53:02
[quote:a2fec3c7f5="HonestQiao"]

哦,我很受打击的,你这么说。

管它哪,这年头,好酒也怕巷子深;要是大家喜欢的话,也可以成为好酒[/quote:a2fec3c7f5]

我那时候的方法跟你的不一样的,所以没敢拿出来
那时候是遍历Request.Form数组,根据名字来赋值的 :oops: 
比如radio就取名radio_xxx,text就取名text_xxx :cry:

 HonestQiao 回复于:2005-04-18 17:53:59
[quote:fa5eedfff1="imbiss"]:lol: 
抱歉跑题了。
你的代码大致看了一下。我
不知道你说的作的更好是指什么,或者说哪方面能做的更好?
 :mrgreen:[/quote:fa5eedfff1]


我不是有说明的吗?
大哥你强,直接就看代码了。不过希望可以看懂。

 geel 回复于:2005-04-18 20:29:03
有朋友问为什么不用cookie?答:客户端cookie有大小限制的,所以不用cookie
而session可以自定义它的行为,所以想怎么办就怎么办了

 tkmxxg 回复于:2005-04-19 10:18:15
如果全是多选项
可以用无限分类方法先列出来,
再如这样:
for($i=0;$i<count($p_ids);$i++){
  if($p_ids[$i]) {
    $p_id.=$p_ids[$i].",";
  }
}

 HonestQiao 回复于:2005-04-22 22:23:59
你这个也不错的。

 ftpw 回复于:2005-04-23 11:10:48
表笑,看结构斗知道我很菜的。所有要提交的内容斗放在session里面。

........
.........
     if(trim($_POST['normal_habit'])=="")
        $error = $error."至少选择一项爱好;<br></br>";
     else{
     $str_normal_habit = "";
     //$_SESSION['normal_habit'] = "";
     if(!empty($_POST['normal_habit']) and is_array($_POST['normal_habit'])){
        if(sizeof($_POST['normal_habit'])>6)
          $error = $error."最多只能选择六项爱好;<br><br>";
        foreach ($_POST['normal_habit'] AS $code){
             $str_normal_habit = $str_normal_habit." ".$code;
        };
        $_SESSION['normal_habit'] = trim($str_normal_habit);
     }
     }
...........
..........
          <?php
             $normal_habit_query = $DB->query("select code , comment from n_normal_habit order by code asc");
             $count = 0;
             $normal_habit_items = explode(" ",$_SESSION['normal_habit']); 
           
            while($normal_habit=$DB->fetch_array($normal_habit_query)){
               if($count==5) {
                echo "<br>";
                $count = 0;
               }
               if($normal_habit['code']!= "13" and $normal_habit['code']!= "15" )
                echo "<input type=\"checkbox\" ".(in_array($normal_habit['code'],$normal_habit_items)?" CHECKED ":" ")."name=\"normal_habit[".$normal_habit['code']."]\" value=\"".$normal_habit['code']."\">".$normal_habit['comment']."&&";
               else
                echo "<input type=\"checkbox\" ".(in_array($normal_habit['code'],$normal_habit_items)?" CHECKED ":" ")."name=\"normal_habit[".$normal_habit['code']."]\" value=\"".$normal_habit['code']."\">".$normal_habit['comment'];
               $count++;
            } 
          ?> 
........
.......

 HonestQiao 回复于:2005-04-23 13:36:41
呵呵,如果这么做确实太麻烦了,还是把页面和程序分开的好啊

 ftpw 回复于:2005-04-24 19:49:10
[quote:b1b5b75173="HonestQiao"]呵呵,如果这么做确实太麻烦了,还是把页面和程序分开的好啊[/quote:b1b5b75173]

我也不想,但是我还不会那个叫模板的东东,听说模板有几种,不知道用哪种实用点?

 phphp 回复于:2005-04-26 16:15:33
分类还值得看看,后面的就没必要了,
每次都给服务器..
不如压缩后用隐藏字段传递[/b]

 zywhao 回复于:2005-05-07 19:25:02
看起来有点晕

 qiufeng1737 回复于:2005-05-07 22:53:50
此时感觉PHP中对变量的应用不太好,直接在代码中随便用了,看别人的代码时感觉对不好号~

原文转自:http://www.ltesting.net