0

我正在尝试制作一个可以在多个页面上使用的功能,以节省使用的代码量。函数参数之一应该告诉函数从哪个 mysql 表中获取所有数据,但由于某种原因,该函数不起作用。这是我所拥有的:

function get_data($conn, $type) {
    $stmt = $conn->prepare("SELECT * FROM :type");
    $stmt->bindParam(':type', $type);
    $stmt->execute();
    $results = $stmt->fetchAll();
    return $results ? $results : false;
}

因此,当我在我的一个页面上调用该函数时,我使用:

$conn = connect();
$results = get_data($conn, 'links');

为什么功能不起作用?有人知道吗?

4

2 回答 2

1

据我所知,您不能将表格作为参数传递。因此,您必须使用字符串连接构建查询。在这种情况下,SQL 注入的风险应该为零,因为您不应该接受来自外部来源的表名。

例子

function get_data($conn, $table_name) {
    // The backticks are used in case table name contains spaces, or it matches a keyword
    $stmt = $conn->prepare('SELECT * FROM `' . $table_name . '`');
    $stmt->bindParam(':type', $type);
    $stmt->execute();
    $results = $stmt->fetchAll();
    return $results ? $results : false;
}

进一步说明
虽然我可以理解您想要实现的目标,但这种访问数据的方法效率很低。首先,您使用星号,这通常是运行查询时的一大禁忌。其次,使用这种方法,您不能添加子句,例如 WHERE、JOIN 等。总是不加选择地从表中获取所有数据可能会导致主要的性能问题。

于 2012-11-21T00:16:35.683 回答
1

@Diego 是正确的,您不能将 SQL 参数用于表名、列名、SQL 关键字、值列表(如在 IN() 谓词中)或任何其他表达式。

SELECT :column FROM table   -- NO, unless you want to select a constant string

SELECT * FROM :table    -- NO

SELECT * FROM table WHERE column IN (:list)  -- NO

SELECT * FROM table ORDER BY :column -- NO

SELECT * FROM TABLE ORDER BY column :asc_or_desc  -- NO

基本上,请记住这条规则:如果您可以用一个常量值(例如,带引号的字符串、日期或整数)代替 SQL 参数,那么这是对参数的合法使用。否则,没有。

SELECT :string FROM table -- OK, but returns value of :string for every row

SELECT * FROM table WHERE column = :string  -- OK

SELECT * FROM table WHERE column IN (:x, :y, :z) -- OK, one parameter per value

prepare()此外,在编程 PDO 时,您应该始终检查和的返回值execute()。它们将返回false错误,您应该编写代码来检测并做出适当的响应(即记录错误、显示错误页面、给用户另一个机会等)

$stmt = $conn->prepare("SELECT * FROM :type"); // illegal use of parameter
if ($stmt === false) {
  // check $pdo->errorInfo(), see documentation
}
$stmt->bindParam(':type', $type);
$status = $stmt->execute();
if ($status === false) {
  // check $stmt->errorInfo(), see documentation
}

您甚至可能想要检查其他 PDO 函数的返回值。请参阅文档,其中许多返回false错误。

于 2012-11-21T00:19:36.170 回答