由于我还在学习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['?'];
问号说,我不知道期望什么列,因为它的名称可以是数据库中的表格中的任何内容!
由于我有几个表,查询将在表上为零,但每个表中的列名不同,所以我希望能够使用一个可以从这样的列中输入的查询。
我希望我的问题很明确,我不是要求不可能的事。如果它含糊不清,我想澄清(希望如此)。
答案 0 :(得分:3)
我不确定你的意思,但是可以通过键入index(从0开始)来引用特定列,如下所示:$row[0], $row[1]
其中0表示第一列,1表示第二列来自返回的记录集。
示例:强> 如果您有这样的select语句:
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)
答案 1 :(得分:2)
由于你学习,我们可能需要一些时间来解释为什么这是可能的,但很多人(包括我自己)会说这是坏 - 或者至少危险
您的SQL查询基本上是您发送到数据库服务器的文本字符串,它解码该字符串,尝试将其解释为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
将成为DB服务器收到的:
select * FROM myTableContainigSecretData WHERE id=1; DELETE * FROM myImportantTable;
可能不是你想要的。
我在此尝试演示的内容称为SQL injection。这是Web应用程序中一个非常常见的错误。
防止SQL注入的最佳方法是使用预处理语句来替换查询中的某些占位符 values 正确屏蔽以防止 SQL注入。几分钟之前发布了一个示例作为对另一个问题的回复:https://stackoverflow.com/a/18035404/2363712
关于您的初始问题的“问题”是将替换值而不是表格或列标识符。
如果您确实想要通过变量内容替换表/列标识符(或查询的其他非值部分),则必须自己检查每个变量的内容以防止SQL注入。这很可行。但那是一些工作......