PDO-将字段名作为变量传递


PDO - passing a field name as a variable

我刚刚将代码从mysql_query样式的命令迁移到PDO样式,遇到了一个问题。旧代码看起来是这样的:

$query_list_menu = "SELECT ".$_GET['section_name']." from myl_menu_hide_show WHERE id='".$_GET['id']."'";

更新后的代码如下所示。显然它不起作用。我在$_GET['section_name']中存储了一个字符串,该字符串表示数据库中的字段名。但我认为当我把它作为一个变量传递时会出现问题。以下代码有效吗?谢谢

$query_list_menu = "SELECT :section_name from myl_menu_hide_show WHERE id=:id";
$result_list_menu = $db->prepare($query_list_menu);
$result_list_menu->bindValue(':section_name', $_GET['section_name'] , PDO::PARAM_STR);
$result_list_menu->bindValue(':id', $_GET['id'] , PDO::PARAM_INT);  
$result_list_menu->execute();

如果$_GET['section_name']包含列名,则查询应为:

$query_list_menu = "SELECT " . $_GET['section_name'] . " from myl_menu_hide_show WHERE id=:id";

给予:

$query_list_menu = "SELECT :section_name from myl_menu_hide_show WHERE id=:id";
$result_list_menu = $db->prepare($query_list_menu);
$result_list_menu->bindValue(':id', $_GET['id'] , PDO::PARAM_INT);  
$result_list_menu->execute();

原因是您希望列的实际名称在查询中——您已经将其更改为参数,这实际上没有多大意义。

我还要补充一点,像这样直接使用$_GET['section_name']是一个巨大的安全风险,因为它允许SQL注入。我建议您在构建和执行查询之前,通过对照列列表检查$_GET['section_name']的值来验证它。

没有一种好的、安全的方法可以根据用户的选择从记录中只选择一个字段。最明智的解决方案是选择整行,然后返回唯一请求的字段

$sql = "SELECT * from myl_menu_hide_show WHERE id=?";
$stmt = $db->prepare($query_list_menu);
$stmt->execute([$_GET['id']]);
$row = $stmt->fetch();
return $row[$_GET['section_name']] ?? false;