0

我是 sql 和 PHP 的新手。到目前为止已经能够解决问题,但是 PREPARE 语句给了我语法问题(可能是因为我试图一步完成几件事)。如果有人能让我知道我的语法在哪里搞砸了,那就太好了。

此外,我正在编写的代码正在尝试更新服务器上的保存文件,虽然我相信使用 prepare 语句执行此操作是正确的方法,但如果不是,我会很高兴听到。注意我计划更改 INSERT INTO -> 有条件的插入或更新。

我得到的错误是意外的 T_STRING。我已经在代码中标记了错误所在的行。

$sql='PREPARE statement FROM "INSERT INTO buildings VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) WHERE id="$id" AND ind="$i""';
$result=mysql_query($sql);
for($i=0;$i<1600;$i+=1){
    if(isset($_POST['ind'.$i])){
        $bind=$_POST['bind'.$i];
        $time=$_POST['time'.$i];
        $level=$_POST['level'.$i];
        $p1ind=$_POST['p1ind'.$i];
        $p1state=$_POST['p1state'.$i];
        $p1time=$_POST['p1time'.$i];
        $p2ind=$_POST['p2ind'.$i];
        $p2state=$_POST['p2state'.$i];
        $p2time=$_POST['p2time'.$i];
        $p3ind=$_POST['p3ind'.$i];
        $p3state=$_POST['p3state'.$i];
        $p3time=$_POST['p3time'.$i];
        $p4ind=$_POST['p4ind'.$i];
        $p4state=$_POST['p4state'.$i];
        $p4time=$_POST['p4time'.$i];
        $p5ind=$_POST['p5ind'.$i];
        $p5state=$_POST['p5state'.$i];
        $p5time=$_POST['p5time'.$i];

        $sql = 'SET @bind="$bind",'. //<-line of error
        '@time="$time",'.
        '@level="$level",'.
        '@p1ind="$p1ind",'.
        '@p1state="$p1state",'.
        '@p1time="$p1time",'.
        '@p2ind="$p2ind",'.
        '@p2state="$p2state",'.
        '@p2time="$p2time",'.
        '@p3ind="$p3ind",'.
        '@p3state="$p3state",'.
        '@p3time="$p3time",'.
        '@p4ind="$p4ind",'.
        '@p4state="$p4state",'.
        '@p4time="$p4time",'.
        '@p5ind="$p5ind",'.
        '@p5state="$p5state",'.
        '@p5time="$p5time",'.
        '@id="$id",'.
        '@ind="$i"';
        $result=mysql_query($sql);
        $sql='EXECUTE statement USING @id,@time,@level,@p1ind,@p1state,@p1time,@p2ind,@p2state,@p2time,@p3ind,@p3state,@p3time,@p4ind,@p4state,@p4time,
        @p5ind,@p5state,@p5time,@ind,@bind';
        $result=mysql_query($sql);
        if(!$result){
            die("saveArry[0]=".mysql_error().";");
        }else{
            die("saveArry[0]='saved';");
        }
    }
}
$sql='DEALLOCA PREPARE statement';
$result=mysql_query($sql);

更新我无法在我的主机服务器上安装 PDO,因此很遗憾 PDO 是一个不可接受的解决方案。我的回答(现在没有错误!):

    if(isset($_POST['ind'])){
    $ind=sanitizeString($_POST['ind']);
    $bind=sanitizeString($_POST['bind']);
    $time=sanitizeString($_POST['time']);
    $level=sanitizeString($_POST['level']);
    $p1ind=sanitizeString($_POST['p1ind']);
    $p1state=sanitizeString($_POST['p1state']);
    $p1time=sanitizeString($_POST['p1time']);
    $p2ind=sanitizeString($_POST['p2ind']);
    $p2state=sanitizeString($_POST['p2state']);
    $p2time=sanitizeString($_POST['p2time']);
    $p3ind=sanitizeString($_POST['p3ind']);
    $p3state=sanitizeString($_POST['p3state']);
    $p3time=sanitizeString($_POST['p3time']);
    $p4ind=sanitizeString($_POST['p4ind']);
    $p4state=sanitizeString($_POST['p4state']);
    $p4time=sanitizeString($_POST['p4time']);
    $p5ind=sanitizeString($_POST['p5ind']);
    $p5state=sanitizeString($_POST['p5state']);
    $p5time=sanitizeString($_POST['p5time']);
    $rot=sanitizeString($_POST['rot']);
    $sql="INSERT INTO buildings (id,ind,bind,time,level,p1ind,p1state,p1time,p2ind,p2state,p2time,p3ind,p3state,p3time,p4ind,p4state,p4time,p5ind,
    p5state,p5time,rot) VALUES ('$id','$ind','$bind','$time','$level','$p1ind','$p1state','$p1time','$p2ind','$p2state','$p2time','$p3ind','$p3state',
    '$p3time','$p4ind','$p4state','$p4time','$p5ind','$p5state','$p5time','$rot') ON DUPLICATE KEY UPDATE bind='$bind',time='$time',level='$level',
    p1ind='$p1ind',p1state='$p1state',p1time='$p1time',p2ind='$p2ind',p2state='$p2state',p2time='$p2time',p3ind='$p3ind',p3state='$p3state',
    p3time='$p3time',p4ind='$p4ind',p4state='$p4state',p4time='$p4time',p5ind='$p5ind',p5state='$p5state',p5time='$p5time',rot='$rot'";
    $result=mysql_query($sql);
    if(!$result){
        die("saveArry[0]=".mysql_error().";");
    }else{
        die("saveArry[0]=saved;");
    }
}
4

2 回答 2

1

单引号和双引号在该行中互换,应该是,

 $sql = "SET @bind='$bind', 
    @time='$time',
    @level='$level',
    @p1ind='$p1ind',
    @p1state='$p1state',
    @p1time='$p1time',
    @p2ind='$p2ind',
    @p2state='$p2state',
    @p2time='$p2time',
    @p3ind='$p3ind',
    @p3state='$p3state',
    @p3time='$p3time',
    @p4ind='$p4ind',
    @p4state='$p4state',
    @p4time='$p4time',
    @p5ind='$p5ind',
    @p5state='$p5state',
    @p5time='$p5time',
    @id='$id',
    @ind='$i'";
于 2012-11-13T22:43:40.670 回答
1

我强烈建议使用PDO而不是已弃用的 mysql_* 函数。它以透明的方式为您准备好声明来完成艰苦的工作。

正如 EthanB 在评论中指出的那样,您的代码容易受到SQL 注入的影响,因为您直接从用户输入($_POST变量)插入值。

使用 PDO,您的代码将如下所示(简化):

$statement = $pdo->prepare("INSERT INTO buildings VALUES(:ind, :bind, :time, :level, ...) WHERE id = :id AND ind = :ind");

for( ... ) {
    $statement->execute(array(
       ":ind" => $_POST["ind" . $i],
       ":bind" => $_POST["bind" . $i], ...
    ));
}

PDO 将为您发送 PREPARE 和 EXECUTE 查询并转义所有参数以防止 SQL 注入。

于 2012-11-13T22:48:31.810 回答