准备好的声明让命令不同步;你现在不能运行这个命令

时间:2013-08-09 02:52:08

标签: php mysqli prepared-statement

我已经阅读了我能想到的所有内容以获得解释但似乎没有任何帮助。如果有人可能能够指出显而易见的事情,或者让我略微知道出了什么问题。我已经阅读了php.net和mysqli标签,似乎无法弄清楚这一点。我读到的一切都说你不能发两个查询,但我只是尝试一个。任何帮助将不胜感激。

This-> https://stackoverflow.com/a/9649149/1626329 - 可能我有多个结果集的状态,但我不确定这对于准备好的语句的内部工作原理有什么意义或我可以做些什么。

我的代码:

class mydb {

    public function __construct() {
        // Connect to Database
        $this->mydb = new mysqli('****', '***', '***', '***');
        if ($this->mydb->connect_errno) { // Error on connection failure
            echo "Failed to connect to MySQL in Construct: (" . $this->mydb->connect_errno . ") " . $this->mydb->connect_error;
        }
    }

    public function choose ($select, $from, $config = 0, $options = NULL) {
        if ($config === 0) { /** Configure statement for prepare depending on options */
            $stmt = 'SELECT ' . $select . ' FROM ' . $from;
        } elseif ($config === 1) {
            $stmt = 'SELECT ' . $select . ' FROM ' . $from . ' WHERE ' . $options['where_comp'] . ' LIKE ?';
        } elseif ($config === 2) {
            $stmt = 'SELECT ' . $select . ' FROM ' . $from . ' WHERE ' . $options['where_comp'] . ' = ?';
        } /** End if/elseif Prepare statemenet */
        $mydb = $this->mydb->prepare($stmt);
        if ($config === 1 || $config === 2) {
            $mydb->bind_param("s",$options['where_value']);
        }

        if ($mydb->execute()) { /** If execute is good then get results */
            $result = $mydb->get_result();
            $payload = array();
            while ($row = $result->fetch_array(MYSQLI_NUM)) {
                $payload[] = $row;
            }
            return $payload;
        } /** End if results */
    } /** End choose class method */
} /** End mydb Class */

$myDB = new mydb();

$agentArray = $myDB->choose('*','`agent`');

使用php.net示例并对其进行修改以显示更好的示例:

$mysqli = new mysqli('host', 'database', 'user', 'pass');
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!($stmt = $mysqli->prepare("SELECT ? FROM ?"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

if (!($res = $stmt->get_result())) {
    echo "Getting result set failed: (" . $stmt->errno . ") " . $stmt->error;
}

for ($row_no = ($res->num_rows - 1); $row_no >= 0; $row_no--) {
    $res->data_seek($row_no);
    var_dump($res->fetch_assoc());
}
$res->close();

2 个答案:

答案 0 :(得分:1)

此页面上“相关”部分的第一个结果(意味着在您撰写问题的过程中提供给您)offers a solution

作为一般规则,根据错误消息很容易找到问题的答案。只有你需要的不是停留在第一个搜索结果,而是继续前进。

然而,在你的choose()函数上。我觉得这很不切实际,不安全,没用:

  • 不切实际,因为它不允许您使用SQL,而是使用SQL的一个非常有限的子集。
    • 并且它使您的代码非常难以理解。
  • 不安全,因为它确实不为所有动力部件提供保护,但仅限于值
  • 没用,因为它可以为你节省多少钱。

看,你认为自己保存了2个单词 - SELECTFROM

 $agentArray = $myDB->choose('*','`agent`',1,
               array('where_comp' => 'name', 'where_value' -> "%bob%"));

但是你使这段代码难以理解,难以维护,无法运行最简单的JOIN。为什么不去做。更不用说实际代码比传统的SQL查询更长

$sql = 'SELECT * FROM `agent` WHERE name LIKE ?';
$agentArray = $myDB->query($sql, "%bob%");

哪一个更容易阅读?

答案 1 :(得分:-1)

添加if语句以正确显示错误实际上会提供可以使用的mysql错误响应:

if (!($stmt = $mysqli->prepare("SELECT ? FROM ?"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

错误回复: Prepare failed: (1064) You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1

- 您不能通过prepared-statements传递标识符,只应将它用于从用户输入传递的值。