准备好的语句:';附近有错误;?其中`quantity`=';


Prepared Statements: error near '? WHERE `quantity`=?'

我正在尝试使用准备好的语句来验证表单,我希望能够在多个表单中使用相同的代码。我想坚持DRY方法。

每个表单将包含不同的表单名称(表示数据库表的隐藏字段),并具有不同的属性(选择列表中表示MYSQL数据库中列的值),这些属性需要在添加到购物车之前进行验证。

出于某种疯狂的原因,价格添加是在JS中完成的(我知道这是一种糟糕的添加价格的方式,但这是我唯一的选择,不幸的是,这不是一种选择)。表单需要经过验证,以确保用户没有为了节省一些钱而篡改表单。因此,我检查的方法是从表单中获取值,并将它们与数据库中的值进行比较,以确保它们是相同的。如果其中任何值与数据库中不同,则表单无效。我不断收到关于SQL语句的错误。特别是它没有准备声明

以下是带有准备好的语句的PHP代码:

<?php
        ///////MYSQL Login Data/////
        $user = "root";
        $password = "";
        $database = "printoptions";
        ///////MYSQL loging Data ///////
        //Grab the quantity selected from the form
        $quantity = explode('|+', $_POST['quantity']);
        //Set quantity to be only the numerical value not the add amount part
        $quantity = $quantity[0];
        //what is the name of the form? This comes from a hidden field
        $formname = $_POST['formname'];
        //instantiate mysqli object used for db queries
        $mysqli = new mysqli("localhost", $user, $password, $database);
        //If there is an error connecting to the database spit it out and tell me what the error is
        if ($mysqli->connect_errno) 
        {
            echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
        }
        //Start our prepared statment
        //The query is:
        //SELECT `$attribute` FROM `$formname` WHERE `quantity` = $quantity
        if (!($stmt = $mysqli->prepare('SELECT ? FROM ? WHERE `quantity`=?'))) 
        {
            echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
        }
        //Loop Through each Post value
        foreach ($_POST as $name => $value) 
        {
            //make sure we don't grab formname and quantity just get all the attributes and leave those alone
            if ($name != 'formname' AND $name != 'quantity') 
            {
                //Prepared statement do our bind and execute
                //the attribute is the field values first part before the |+
                //so explode the $value
                $attribute = explode('|+', $value);
                //Assign just the first part
                $attribute = $attribute[0];
                //do the binding string, string, float(double)
                if (!$stmt->bind_param("sss", $attribute, $formname, $quantity)) 
                {
                    echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
                }
                //execute the query based on the binded paramaters
                if (!$stmt->execute()) 
                {
                    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
                }
                //Bind the results of the query temporarily to $result
                $stmt->bind_result($result);
                //If the result of the query is NOT equal to the value of the field make it fail validation
                if ($result != $value) 
                {
                    //What to do if it fails validation
                    echo "Validation Failed You little Cheater!";
                } else
                {
                    //What to do if it passes validation
                    echo "Validation Success!";
                }
                 //end if checking form values aginst DB values
            }
             //end if excluding formname and quantity
        }
         //end foreach loop

然后表单HTML本身只是为了澄清|+之前值的第一部分是列名,而第二部分是价格的添加量。因此:value="columnName|+priceIncrease"

<form action="post.php" method="post">
            <input type="hidden" name="formname" value="brochure">
        <div>
            <select name="quantity" id="ff_elem13">
                <option value="1000|+550.00">1000</option>
                <option value="2500|+900.00">2500</option>
            </select>
        </div>
        <div>
            <select name="fold" id="ff_elem14">
                <option value="foldBi|+15.00">Bi Fold</option>
                <option value="foldTri|+20.00">Tri Fold</option>
            </select>
        </div>

        <div>
            <select name="color" id="ff_elem15">
                <option value="color40|+15.00"> Color 4:0</option>
                <option value="color41|+20.00">Color 4:1</option>
            </select>
        </div>

        <div>
            <select name="rush" id="ff_elem16">
                <option value="rush13|+15.00">Rush 1-3 Days</option>
                <option value="rush24|+20.00">Rush 2-4 Days</option>
            </select>
        </div>
            <input type="SUBMIT" value="Submit">
            </form>

我收到的错误是

准备失败:(1064)您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,了解在"?"附近使用的正确语法?其中quantity=?'在第1行

如何修复此问题,以便使用此准备好的语句?我环顾四周,但从未见过有人使用?用于选择实际的表名,而大多数情况下只是人们使用它来插入或更新值。

希望这能很好地解释我的情况,但如果我错过了什么,请告诉我,这样我就能纠正自己。

这是一个设计非常糟糕的表单。绝对有理由将定价嵌入这样的形式值中。如果你想让用户即时反馈他们的选择,那没关系,但你可以将定价存储在一个单独的JS变量中:

<?php
   var prices = <?php echo json_encode($product_ids_and_prices_from_database); ?>;
?>
<script>
    alert("Total cost: " + (prices['color40'] + prices['foldBi']));
</script>

然后,用户可以随心所欲地摆弄这些价格,而且永远不会影响服务器的运行。