PHP MySQLi问题与准备好的语句导致错误

时间:2016-06-07 14:57:20

标签: php mysql mysqli prepared-statement

我在尝试使用php脚本为我的网站工作时遇到问题,我可以将新项目添加到我的在线商店。

我遇到问题的代码段是:

$error = '';
$success = '';

if(isset($_POST['submit']))
{
    define("MAX_SIZE", "4096");

    $errors=0;

    $name = $_POST['name'];
    $price = $_POST['price'];
    $desc = filter_var($_POST['desc'], FILTER_SANITIZE_STRING);
    $image = $_FILES['image']['name'];
    $uploadedfile = $_FILES['image']['tmp_name'];

    if($image)
    {
        $filename = stripslashes($_FILES['image']['name']);
        $extension = getExtension($filename);
        $extension = strtolower($extension);
        if(($extension != "jpg") && ($extension != "jpeg") && ($extension != "png") && ($extension != "gif"))
        {
            $error .= '<p class="error">The file must be one of the following file types(jpg|jpeg|png|gif)</p>';
            $errors=1;
        }
        else
        {
            $size=filesize($_FILES['image']['tmp_name']);

            if($size > MAX_SIZE*1024)
            {
                $error .= '<p class="error">The file cannot exceed 4MB in size.</p>';
                $errors=1;
            }

            if($extension=="jpg" || $extension=="jpeg")
            {
                $uploadedfile = $_FILES['image']['tmp_name'];
                $src = imagecreatefromjpeg($uploadedfile);
            }
            else if($extension=="png")
            {
                $uploadedfile = $_FILES['image']['tmp_name'];
                $src = imagecreatefrompng($uploadedfile);
            }
            else
            {
                $src = imagecreatefromgif($uploadedfile);
            }

            list($width,$height)=getimagesize($uploadedfile);

            $newwidth=128;
            $newheight=128;
            $tmp=imagecreatetruecolor($newwidth,$newheight);

            imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);

            $filename = "../store/images/" . $_FILES['image']['name'];

            imagejpeg($tmp,$filename,100);

            $fname = $_FILES['image']['name'];

            imagedestroy($src);
            imagedestroy($tmp);
        }
    }

    if($name == '')
    {
        $error .= '<p class="error">You must enter a name for the product.</p>';
    }

    if(!preg_match('/^[a-zA-Z\s]+$/', $name))
    {
        $error .= '<p class="error">The product name can only contain letters and spaces.</p>';
    }

    if($_POST['type'] == 'KIT')
    {
        $type = 'KIT';
    }
    else if($_POST['type'] == 'VIP')
    {
        $type = 'VIP';
    }
    else if($_POST['type'] == 'OTHER')
    {
        $type = 'OTHER';
    }
    else
    {
        $error .= '<p class="error">You must select a valid type for the product.</p>';
    }

    if($price == '')
    {
        $error .= '<p class="error">You must enter a price for the product.</p>';
    }

    if(!preg_match('/^\d+(:?[.]\d{2})$/', $price))
    {
        $error .= '<p class="error">You must enter a valid price for the product.</p>';
    }

    if($desc == '')
    {
        $error .= '<p class="error">You must enter a description for the product.</p>';
    }

    $stmt = $db->prepare("SELECT * FROM products WHERE name = ?");
    if($stmt)
    {
        $stmt->bind_param('s',$name);
        $stmt->execute();

        if($stmt->num_rows > 0)
        {
            $error .= '<p class="error">This product already exists. Please choose a different name.</p>';
        }
    }
    else
    {
        $error .= '<p class="error">An error occurred at line 135. Please contact the site administrator.</p>';
    }

    if(empty($error) && !$errors)
    {
        $stmt = $db->prepare("INSERT INTO products (name, image, price, prod_desc, type) VALUES ( ?, ?, ?, ?, ? )");

        if($stmt)
        {
            $stmt->bind_param('sssss', $name, $fname, $price, $desc, $type);

            if($stmt->execute())
            {
                $success .= '<p class="success">Product added successfully.</p>';
            }
            else
            {
                $error .= '<p class="error">An error occured at line 158. Please contact the site administrator.</p>';
            }
        }
        else
        {
            $error .= '<p class="error">An error occured at line 154. Please contact the site administrator.</p>';
        }
    }
}

我遇到问题的部分是if(空($ error)&amp;&amp;!&amp; errors)语句之后的if($ stmt)块。

根据我用于PHP本身和MySQL插入查询的每个语法检查器,它们都报告没有错误。但它不断吐出第154行的错误,我无法弄清楚原因。我已经验证了变量是通过回显它们从表单中正确存储的,我还验证了mysql表的列确实存在,拼写正确。

这开始让我疯了,当我尝试使用$ stmt-&gt;错误或$ db-&gt;错误回应出mysql错误时,它返回空白,没有列出任何错误。

我得到的唯一结果就是当我做了返回0的mysqli_errno($ db)时。

任何人都知道这段代码有什么问题,或者为什么它不起作用?

表单的HTML标记:

<div id="form">
<form action="" method="post" enctype="multipart/form-data">
<table>
<th colspan="2">Add to Store</th>
<tr>
<td colspan="2">
<p>Please use the form below to add items to the store.</p>
<?php

if($error)
{
    echo $error;
}

if($success)
{
    echo $success;
}

?>
<hr>
<tr>
<td><label for="name">Product Name:</label></td>
<td><input type="text" name="name" id="name" value="<?php if(isset($name)) { echo $name; } else { echo ''; } ?>" /></td>
</tr>

<tr>
<td><label for="price">Product Price:</label></td>
<td><input type="text" name="price" id="price" size="6" maxlength="6" value="<?php if(isset($price)) { echo $price; } else { echo ''; } ?>" /></td>
</tr>

<tr>
<td><label for="image">Product Image:</label></td>
<td><input type="file" name="image" id="image" /><br /><small>File must be 128x128 pixels, and no larger than 4MB.</small></td>
</tr>

<tr>
<td><label for="type">Product Type:</label></td>
<td>
<select name="type">
<option value="VIP">VIP Package</option>
<option value="KIT">Donator Kit</option>
<option value="OTHER">Other</option>
</select>
</td>
</tr>

<tr>
<td colspan="2"><label for="desc">Product Description:</label></td>
</tr>
<tr>
<td colspan="2"><textarea name="desc" style="width: 500px; height:250px;"><?php if(isset($desc)) { echo $desc; } ?></textarea></td>
</tr>

<tr>
<td colspan="2"><input type="submit" name="submit" id="submit" value="Add Product" /></td>
</tr>

</table>
</form>
</div>

2 个答案:

答案 0 :(得分:1)

因此在经历了很多头痛之后,我找到了解决方法。

问题的根源在这里:

$stmt = $db->prepare("SELECT * FROM products WHERE name = ?");
    if($stmt)
    {
        $stmt->bind_param('s',$name);
        $stmt->execute();

        if($stmt->num_rows > 0)
        {
            $error .= '<p class="error">This product already exists. Please choose a different name.</p>';
        }
    }
    else
    {
        $error .= '<p class="error">An error occurred at line 135. Please contact the site administrator.</p>';
    }
将此更改为以下后

$sql = "SELECT * FROM products WHERE name = '".$name."' LIMIT 1";
    $result = $db->query($sql);

    if(is_object($result) && $result->num_rows == 1)
    {
        $error .= '<p class="error">This product already exists. Please choose a different name.</p>';
    }

一切都很开心,现在没有问题。仍然不确定为什么原始代码不起作用,但它现在有效。感谢您的帮助。

答案 1 :(得分:1)

您从未获取任何结果,因此num_rows将始终为零。有一个简单的补丁,使用store_result()

$stmt->bind_param('s',$name);
$stmt->execute();
$stmt->store_result();

if($stmt->num_rows > 0)
{
    $error .= '<p class="error">This product already exists. Please choose a different name.</p>';
}

但是,您的代码所需要的远远不止这些。您确实应该重写它,避免太多嵌套if语句。也使用正确的错误报告。