在不知道列名的情况下获取Mysql结果


Getting a Mysql Results without knowing a column name

由于我仍在学习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['?'];

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

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

我希望我的问题很清楚,我不是在要求不可能的事情。如果有歧义,我愿意澄清(希望如此)。

我不知道你的意思,但可以通过键入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)

由于您正在学习,我们可能需要一些时间来解释为什么这是可能的,但许多人(包括我自己)会说这是糟糕——或者至少危险

为什么你可以

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

由于所有发送到DB服务器的都是文本字符串,因此可以根据需要构建该字符串。比如使用字符串插值:

select * FROM $book_categories WHERE id=$id

这样,您就可以用变量的内容替换查询的任何部分。你甚至可以走得更远:

$query FROM $book_categories WHERE id=$id

其中CCD_ 6可以由CCD_ 7或CCD_。
为什么不从一个表单初始化所有这些变量呢:

$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

";"问题";关于您最初的问题,它将替换,而不是表或列标识符

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