准备好的声明问题

时间:2012-03-16 18:08:15

标签: php sql

我有这个代码(有效):

if (isset($_POST['plant_name']) && $_POST['plant_name']) {
$where .= "AND (common_name) LIKE '".strtolower($_POST['plant_name']) . "' OR (latin_name) LIKE '".strtolower($_POST['plant_name'])."%' ";
}

但是我想把它改成准备好的陈述,我的尝试在下面,但我得到错误:

$plant_name = $_POST['plant_name'];

if (isset($_POST['plant_name']) && $_POST['plant_name']) { 
$stmt = $conn2->prepare . $where .= "AND (common_name) LIKE '".'?'. "' OR (latin_name) LIKE '".'?'."%' ";
}

$stmt->bind_param('s', $plant_name);

$stmt->execute();

有人可以帮帮我吗

我的错误是:

Notice: Undefined property: mysqli::$prepare

Fatal error: Call to a member function bind_param() on a non-object

1 个答案:

答案 0 :(得分:3)

编辑:你使用mysqli而不是PDO我的错。不幸的是,mysqli不支持命名参数。

在您的原始示例中,您将$conn2->prepare视为属性,但它是一个函数。

试试这个:

// Presumably by this point you have a $sql and a $where that you're appending to.
if (isset($_POST['plant_name']) && $_POST['plant_name']) { 
    $where .= "AND (common_name) LIKE ? OR (latin_name) LIKE ?";
}
$stmt = $conn2->prepare($sql . $where);
if (isset($_POST['plant_name']) && $_POST['plant_name']) { 
    $stmt->bind_param('s', strtolower($_POST['plant_name']));
    $stmt->bind_param('s', strtolower($_POST['plant_name'])."%");
}

这是PDO方式(我认为它更清洁,但此时可能不值得从mysqli更改为PDO):

$statement = $conn2->prepare(
"UPDATE tablename SET 
    field1 = :value1,
    field2 = :value2
WHERE common_name LIKE :plant_name
OR    latin_name LIKE :plant_name
");
$statement->bindValue('value1', $_POST['field1']);
$statement->bindValue('value2', $_POST['field2']);
$statement->bindValue('plant_name', strtolower($_POST['plant_name']));

请注意以下几点:

  1. 我将您从使用?(数字索引占位符)转换为:name(基于名称的占位符)。由于您使用相同的值来搜索这两个字段,因此可以获得非常小的性能提升,并使SQL更具可读性。
  2. 您不希望在绑定参数周围添加引号。绑定参数的一个优点是它们不需要引用转义。 SQL在与参数值不同的通道上发送。所以没有SQL注入的机会。数据库注意到绑定参数,并通过在绑定参数数据中查找它自己读取正确的值。