我想我理解你想要做什么,但你完全以错误的方式去做。当您构建 SQL 查询以发送到数据库时,该 SQL 查询只是一个字符串,不包含任何功能。您可以随心所欲地构建它,但数据库只会看到结果字符串。
在您的代码中,您有一整套这样的行:PHPhtmlspecialchars(question, ENT_QUOTES)
正在解释这些行以构建查询。PHP 有一个有点可疑的特性,即不带引号的名称可能是一个常量,但如果不是,则假定它是字符串;字符串中没有 , , , 或 的实例,因此无论您传入什么选项,都不会对其进行修改。简而言之,写作与写作相同。question
'question'
'question'
<
>
&
"
'
htmlspecialchars
htmlspecialchars(question, ENT_QUOTES)
'question'
然后,您将 ( .
) 该固定字符串与另一个包含一些单引号的固定字符串连接起来:".... '" . htmlspecialchars(question, ENT_QUOTES) . "' ...."
所以你的查询实际上是这样结束的:
$sql="select id,
'question',
'option1',
'option2',
'option3',
'option4',
'correctAnswer',
'category',
'section',
'chapter'
from $user order by id";
下一个奇怪的事情是,您从中选择的表是用一个变量指定的。表名通常不会更改,因此通常不需要变量,尽管偶尔配置它们可能很有用。如果这就是你正在做的,我会建议一个更明确的变量名,比如$db_table_name_user
.
但是,查看列名,它们看起来不像用户的列,所以我想知道您实际尝试做的是否是从基于某个特定用户的问题表中检索。为此,您将需要一个WHERE
子句,或者可能需要JOIN
到另一个表上。如果您不知道它们是如何工作的,请阅读 SQL。
但是,假设它$user
包含数据库表的名称,上面的内容实际上将作为一个成功的 SQL 查询运行 - 只是不是特别有用,因为它将选择id
每个用户的 ,以及文字字符串'question'
,'option1'
等。你需要删除它们,或者用反引号替换它们,这是 MySQL 用来引用列和表名的方法,以避免它们被解释为其他东西。
这将检索user
表中所有内容的详细信息,假设它是这样的:
$db_table_name_user = 'user';
$sql="select id,
question,
option1,
option2,
option3,
option4,
correctAnswer,
category,
section,
chapter
from $user order by id";
现在我们来看看您实际尝试实现的目标:处理从数据库返回的内容htmlspecialchars
中的转义。这与您如何编写查询无关,仅与您之后所做的事情有关。您的数据库表应该存储输入的确切文本:当您将其插入数据库时,您将使用(或参数化的准备查询)来确保数据库不会将其解释为查询的一部分,但这只是关于如何你发送它,而不是它是如何存储的。mysqli_real_escape_string
然后,当您实际在 HTML 页面上显示文本时,从数据库中检索到文本后,您将对其进行转义,以便浏览器不会将其解释为标记的一部分。转义通常应该尽可能晚地发生,这样您就不必假设某些字符串是否已经被转义。
例如,对于一个编号的问题列表,代码将是这样的:
$all_questions = get_all_questions_from_db();
echo '<ol>';
foreach ( $all_questions as $question )
{
echo '<li>' . htmlspecialchars($question['question']) . '</li>';
}
echo '</ol>';