2

由于我仍在学习 PHP 和 MySQL,我想知道是否可以在不知道表名称的情况下查询表。知道我正在查询的表和我想检索的列,我可以写类似

$book_title=$row['book_title'];

然后我可以稍后在脚本中使用生成的变量。在每种情况下,每个图书类别表都会有一个具有不同名称的感兴趣的列。我有几个正在运行查询的表。我可以通过使用始终计算为正确表名的变量来查询任何表,因为来自用户的所有输入都对应于数据库中的表,因此 $_POST 超级全局将始终带有正确的表名。问题是我有一个

$variable=$row['column'];

在我事先不知道列名的情况下,即使我知道表名。

我的查询很简单,看起来像

query="select * FROM $book_categories WHERE id=$id";
$row = mysqli_fetch_array ($result);
$variable=$row['?'];

问号说,我不知道该期待什么列,因为它的名称可能是数据库中表中的任何内容!

由于我有几个表,查询将在一个表上归零,但每个表中的列名各不相同,所以我希望能够使用一个查询,它可以为我提供来自此类列的条目。

我希望我的问题很清楚,并且我不是在要求不可能的事情。如果它模棱两可,我想澄清一下(希望如此)。

4

2 回答 2

4

我不确定您的意思,但可以通过键入 index(从 0 开始)来引用特定列,如下所示:$row[0], $row[1]其中 0 表示第一列,1 表示返回记录集中的第二列。

示例: 如果您有这样的选择语句:

SELECT title, author FROM books

您可以参考这两列$row[0], $row[1]

如果您尝试获取 的值,$row[2]您将获得一个未分配的值,因为记录集中只有两列(0 和 1)。

如果您有这样的选择语句:

SELECT * FROM book_categories

并且记录集返回三列,然后您可以使用$row[0], $row[1] and $row[2]. $row[3]不存在,因为只有三列(0,1 和 2)

于 2013-08-03T17:50:11.633 回答
2

既然你正在学习,也许我们可以花一些时间来解释为什么这是可能的,但很多人(包括我自己)会说这很糟糕——或者至少很危险

为什么你可以

您的 SQL 查询基本上是您发送到 DB 服务器的文本字符串,它会解码该字符串,试图将其解释为 SQL 以执行查询。

由于您发送到数据库服务器的所有内容都是文本字符串,因此您可以根据需要构建该字符串。比如像你一样使用字符串插值:

select * FROM $book_categories WHERE id=$id

这样,您可以用变量的内容替换查​​询的任何部分。你甚至可以更进一步:

$query FROM $book_categories WHERE id=$id

在哪里$query可以通过SELECT *DELETE
而且,为什么不从表单中初始化所有这些变量:

$book_categories = $_POST['book_categories'];
$id = $_POST['id'];
$query = $_POST['query'];

太好了,不是吗?嗯,不...

为什么你不应该

这里的问题是“你能相信这些变量只包含可接受的值吗?”。也就是说,如果$book_categories以某种方式解析到您不想(比如说myTableContainigSecretData)的一张表,会追加什么?如果$id解决一些特制的价值1; DELETE * FROM myImportantTable;呢?

在这些情况下,您的查询:

select * FROM $book_categories WHERE id=$id

将成为数据库服务器收到的:

select * FROM myTableContainigSecretData WHERE id=1; DELETE * FROM myImportantTable;

可能不是你想要的。

我在这里尝试演示的称为SQL 注入。这是 Web 应用程序中非常常见的错误。

如何防止这种情况?

防止 SQL 注入的最佳方法是使用准备好的语句将查询中的某些占位符替换为正确屏蔽SQL 注入值。几分钟前发布了一个示例作为对另一个问题的回应:https ://stackoverflow.com/a/18035404/2363712

关于您最初问题的“问题”是它将替换values而不是 table 或 columns identifiers

如果您真的想用变量内容替换表/列标识符(或查询的其他非值部分),则必须检查每个变量的内容以防止 SQL 注入。这是相当可行的。但这是一些工作......

于 2013-08-03T18:04:33.917 回答