PDO准备/执行SQL问题

时间:2014-07-24 14:48:53

标签: php sql pdo prepared-statement

关于PDO准备好的陈述,我有一个问题。

在下面的代码中,示例1使用预准备语句。但是,此代码不会产生所需的结果。示例2产生了所需的结果,但不使用预处理语句。

示例1在SQL字符串中使用?占位符,然后将字符串值绑定到这些占位符,然后执行(如您所料)。

以下代码:

<?php

// debugging
error_reporting(E_ALL);
ini_set("display_errors", 1);

// db vars
$host = 'localhost';
$db_name = 'cakeTut'; 
$db_username = 'root';
$db_password = 'password'; 

// try to connect to db, else catch exception.
try{
    $pdo = new PDO('mysql:host='.$host.';dbname='.$db_name, $db_username, $db_password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch (PDOException $e){
    echo $e->getMessage();
    die();
}

///////////////////////////////////////
// Example 1
///////////////////////////////////////

// query vars
$tablename = 'users';
$id = 'id';
$first_name = 'first_name';
$last_name = 'last_name';

// query string w/placeholders, then prepare query
$sql = "SELECT ?, ?, ? FROM $tablename";
$query = $pdo->prepare($sql);

// binding query vars to placeholders in query string
$query->bindParam(1, $id, PDO::PARAM_STR);
$query->bindParam(2, $first_name, PDO::PARAM_STR);
$query->bindParam(3, $last_name, PDO::PARAM_STR);

// execute query & print out query details for debugging
$query->execute();
$query->debugDumpParams();

// fetch result set & print it
$resultSet = $query->fetchAll();    
print_r($resultSet);

// loop through result set and print cols.
foreach($resultSet as $row) {
    echo $row['id'] . " " . $row['first_name'] . " " . $row['last_name'];
    echo "<br>";
}

///////////////////////////////////////
// Example 2
///////////////////////////////////////

// create query string with out placeholders, prepare and execute
$sql = "SELECT `id`, `first_name`, `last_name` FROM `users`";
$query = $pdo->prepare($sql);
$query->execute();

// get result set & print it
$resultSet = $query->fetchAll();
print_r($resultSet);

// loop through result set and print cols.
foreach($resultSet as $row) {
    echo $row['id'] . " " . $row['first_name'] . " " . $row['last_name'];
    echo "<br>";
}

?>

以下是代码的输出:

示例1 $query->debugDumpParams();

SQL: [25] SELECT ?, ?, ? FROM users Params: 3 Key: Position #0: paramno=0 name=[0] "" is_param=1 param_type=2 Key: Position #1: paramno=1 name=[0] "" is_param=1 param_type=2 Key: Position #2: paramno=2 name=[0] "" is_param=1 param_type=2 

示例1 print_r($resultSet);

Array ( [0] => Array ( [id] => id [0] => id [first_name] => first_name [1] => first_name [last_name] => last_name [2] => last_name ) [1] => Array ( [id] => id [0] => id [first_name] => first_name [1] => first_name [last_name] => last_name [2] => last_name ) [2] => Array ( [id] => id [0] => id [first_name] => first_name [1] => first_name [last_name] => last_name [2] => last_name ) [3] => Array ( [id] => id [0] => id [first_name] => first_name [1] => first_name [last_name] => last_name [2] => last_name ) [4] => Array ( [id] => id [0] => id [first_name] => first_name [1] => first_name [last_name] => last_name [2] => last_name ) )

循环播放示例1的结果集和打印列。:

id first_name last_name
id first_name last_name
id first_name last_name
id first_name last_name
id first_name last_name

示例2 print_r($resultSet);

Array ( [0] => Array ( [id] => 3 [0] => 3 [first_name] => fiona [1] => fiona [last_name] => mac [2] => mac ) [1] => Array ( [id] => 4 [0] => 4 [first_name] => ronan [1] => ronan [last_name] => duddy [2] => duddy ) [2] => Array ( [id] => 5 [0] => 5 [first_name] => tom [1] => tom [last_name] => thumb [2] => thumb ) [3] => Array ( [id] => 30 [0] => 30 [first_name] => ronan [1] => ronan [last_name] => mcl [2] => mcl ) [4] => Array ( [id] => 31 [0] => 31 [first_name] => Admin [1] => Admin [last_name] => admin [2] => admin ) ) 

循环执行示例2的结果集和打印列。:

3 fiona mac
4 ronan duddy
5 tom thumb
30 ronan mcl
31 Admin admin

我错过了什么吗?上面代码中的两个例子都不应该打印出相同的数据,即例2吗?我已经google了,示例1的代码与准备好的语句中的基本示例匹配。

非常感谢, 罗南

2 个答案:

答案 0 :(得分:2)

预备语句占位符只能在查询中表示VALUES。您不能将它们用于表名,字段名或任何其他SQL关键字。

SELECT * FROM foo WHERE (somefield = ?) // ok
SELECT ? FROM foo WHERE (somefield = 2) // bad - cannot use for field name
SELECT * FROM ? WHERE   (somefield = 2) // bad cannot use for table name
SELECT * FROM foo WHERE (somefield = 2) ORDER BY somefield ? // again bad, can't use for sort order
SELECT * FROM foo WHERE (? = 2) // again bad, can't use for field name

答案 1 :(得分:1)

在我阅读时,您不能在PDO中使用表/列名称的参数。 http://php.net/manual/en/book.pdo.php

请注意:

赢了工作:

$sth = $dbh->prepare('SELECT name, colour, calories FROM ?  WHERE calories < ?');

这个工作!

$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < ?');