2012-07-08 80 views
0

我有一个变量($q=$_GET["q"];),我想用它运行准备好的语句。它包含我的数据库表的列名。PDO - 准备好的语句不处理变量的权利

该变量的值来自下拉列表。当我运行以下代码时,输​​出是在列表中选择的确切值。所以它只是一个列名。

$q=$_GET["q"]; 

$dsn = "mysql:host=$host;port=$port;dbname=$database"; 

$db = new PDO($dsn, $username, $password); 

$sql = "SELECT DISTINCT ? FROM repertoire"; 
$stmt = $db->prepare($sql); 
$stmt->execute(array($q)); 

    echo "<select>"; 
    while ($row = $stmt->fetchObject()) { 
     echo "<option>"; 
     echo "{$row->{$q}}"; 
     echo "</option>"; 
     } 
    echo "</select>"; 

然而,当我改变此行$sql = "SELECT DISTINCT ? FROM repertoire";

$sql = "SELECT DISTINCT ".$q." FROM repertoire";的我从数据库中获取所需的行...

我不是用PHP那么好,所以我想这我的语法在某个地方是错误的。

非常感谢您的帮助。

+0

的可能重复[灿PHP PDO语句接受表名作为参数?](http://stackoverflow.com/questions/182287/can-php-pdo-statements-accept-the-table-name-as-参数) – hakre 2012-07-08 23:48:38

+0

当我看到这些类型的问题时,不禁要问,从用户输入中需要什么类型的应用程序来获取表和/或列名。 – Mahn 2012-07-09 00:00:38

回答

2

在PDO中,准备好的语句准备值而不是表格。

您需要处理用户输入并直接引用。

$q=$_GET["q"]; 

// Make sure you sanitize your user inputs using filter_inputs() or similar. 

$dsn = "mysql:host=$host;port=$port;dbname=$database"; 

$colNames = new PDO($dsn, $username, $password); // Create object for getting column names. 
$sql = "DESC repertoire Field"; // SQL for getting column names. 
$stmt = $colNames->prepare($sql); 
$stmt->execute(); 

$colList = $stmt->fetchAll(PDO::FETCH_COLUMN, 0); // Fetch the results into $colList array. 

if (in_array($q, $colList)) { // If the value of $q is inside array $colList, then run. 

    $db = new PDO($dsn, $username, $password); 

    $sql = "SELECT DISTINCT $q FROM repertoire"; 
    $stmt = $db->prepare($sql); 
    $stmt->execute(array($q)); 

     echo "<select>"; 
     while ($row = $stmt->fetchObject()) { 
      echo "<option>"; 
      echo "{$row->{$q}}"; 
      echo "</option>"; 
      } 
     echo "</select>"; 
} 

还可以阅读:Can PHP PDO Statements accept the table or column name as parameter?

编辑:我添加了一个方法来检查,以确保$ q是一个有效的列由基本上是做一个SQL递减为了让所有的列名出表曲目。

+0

好的,这里没有花哨的问号:) 感谢您的帮助! – sldk 2012-07-08 23:30:47

+2

犯错,一个原因,你应该使用预处理语句(参数化查询)是为了防止SQL注入。在这个建议的答案中,这完全没有了。非常糟糕的例子。 – hakre 2012-07-08 23:49:54

+0

@hakre我添加了一个评论,应该检查用户输入,但没有描述如何。我添加了一种方法来确保输入与一个有效的表名称匹配。对用户输入应始终进行消毒和检查的事实表示良好的评论。 – Stegrex 2012-07-08 23:56:17