在下拉列表中选择一个选项的值


selection the value of an option on a dropdown list

我正在开发一个网站,该网站允许学生通过在下拉列表中选择主题并点击按钮来预订培训课程的座位。我创建了一个javascript(ajax)脚本,其中包含一个调用php脚本的函数,该脚本可以减少数据库中的席位数量。但不幸的是,它不起作用。。。我需要你们的帮助,伙计们:这是我的javascript:

<select name="Branche" name="clock" id="clock" onchange="count()"></select>
<a  onclick="count()" class="button">
    <span class="user">Réserver une place</span>
</a>

<script>
    function count(){
        var place = document.getElementByTagName(clock);
        var option = place.options[place.selectedIndex].id;
        alert(option);
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("GET", "count.php?place=" + place,true);
        xmlhttp.send(null);
        xmlhttp.onreadystatechange = function () {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                var reponse = xmlhttp.responseText;
                if(reponse == "yes") {
                    alert("Votre place a été réservé");
                } else {
                    alert("Vous êtes arrivé trop tard !");
                }
            }   
        }
    }
</script>

这是我的php脚本:

try {
    $db = new PDO('mysql:host=localhost;dbname=projet','root','',array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch(Exception $e){
    echo $e->getMessage();
    die();
}
$nom = $_GET['place'];
$sq="SELECT place FROM formation WHERE nom='$nom'";
$re = $db->query($sq);
$i = $re->fetch(PDO::FETCH_ASSOC);
if($i > 0){
    $sqq="UPDATE formation SET place = place - 1 WHERE nom='$nom'";
    $res = $db->query($sqq);
    echo 'yes';
} else {
    echo 'no';
}

第一个错误在这一行:

var place=document.getElementTagName(clock);

您需要根据元素的id而不是其标记名来查找元素。此外,click是不存在的变量;您应该使用带引号的"clock"

var place=document.getElementById("clock");

这样一来,place将成为select元素。但是,稍后您将在构建URL参数时使用此参数:

xmlhttp.open("GET","count.php?place="+place,true);

place不是所选择的值;它是select元素,因此无法正常工作。相反,您应该发送option变量中的值:

xmlhttp.open("GET","count.php?place="+option,true);

这是假设option的值是正确的。如果没有看到HTML和数据库表内容,这在目前是不可能的。

PHP脚本在这里有一个错误:

$i = $re->fetch(PDO::FETCH_ASSOC);
if($i>0){

您使用$i,就好像它是选定的值一样,但事实并非如此。fetch()返回一个带有值的数组,在本例中为一个带有一个值的数组。即使所选的place值为0,您的比较也将始终返回true

此外,您应该更改PHP脚本,这样就不会将值连接到SQL字符串中,因为这会使您容易受到SQL注入的攻击。相反,使用事先准备好的语句。

此外,当存在大量并发时,PHP脚本也不能很好地工作。想象一下,还有一个座位,两个同时进行PHP调用,然后两个都会看到在另一个减少计数之前还有一个位置,两个都得到"是"。

相反,您应该首先执行更新,并在更新语句中检查可用性。然后检查语句是否更新了记录。如果没有,那么就没有地方了。由于update语句在更新期间锁定记录,因此一次只能有一个进程执行此操作。

建立数据库连接后建议使用的PHP代码:

$stmt = $db->prepare("UPDATE formation 
                      SET    place = place - 1 
                      WHERE  nom = ?
                      AND    place > 0");
$stmt->execute(array($_GET['place']));
echo $stmt->rowCount() ? 'yes' : 'no';