我正在努力学习编写查询的最佳方法。 我也明白始终如一的重要性。 直到现在,我都是随意使用单引号,双引号,和反勾号,没有任何真正的思考。
示例:
$query = 'INSERT INTO table (id, col1, col2) VALUES (NULL, val1, val2)';
同样,在上面的示例中,考虑table
,col1
,val1
等可能是变量。
这样做的标准是什么? 你是做什么的?
我已经在这里阅读了大约20分钟类似问题的答案,但似乎这个问题没有明确的答案。
背勾用于表和列标识符,但只有当标识符是MySQL保留关键字,或者标识符包含空格字符或超出有限集合的字符(见下文)时才有必要。通常建议尽可能避免使用保留关键字作为列或表标识符,以避免引用问题。
单引号应用于字符串值,如values()
列表中的字符串值。 MySQL对字符串值也支持双引号,但是单引号被其他RDBMS更广泛地接受,因此使用单引号而不是Double是一个好习惯。
MySQL还要求date
和datetime
文本值作为字符串使用单引号,如'2001-01-01 00:00:00'
。 有关详细信息,请参阅日期和时间文字文档,特别是在日期字符串中使用连字符-
作为段分隔符的替代方法。
因此,在您的示例中,我将双引号引用PHP字符串,并在,'val1','val2'
值上使用单引号。 null
是一个MySQL关键字,是一个特殊的(非)值,因此不加引号。
这些表或列标识符没有一个是保留字,也没有使用需要引用的字符,但我还是用后勾号引用了它们(稍后将详细介绍。。。)。
RDBMS本机函数(例如,MySQL中的now()
)不应被引用,尽管它们的参数受前面提到的字符串或标识符引用规则的约束。
Backtick (`) table & column ───────┬─────┬──┬──┬──┬────┬──┬────┬──┬────┬──┬───────┐ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ $query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`, `updated`) VALUES (NULL, 'val1', 'val2', '2001-01-01', NOW())"; ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑ Unquoted keyword ─────┴┴┴┘ │ │ │ │ │ │ │││││ Single-quoted (') strings ───────────┴────┴──┴────┘ │ │ │││││ Single-quoted (') DATE ───────────────────────────┴──────────┘ │││││ Unquoted function ─────────────────────────────────────────┴┴┴┴┘
变量的引用模式没有改变,尽管如果您打算在字符串中直接插值变量,在PHP中必须双引号。 只需确保您已正确转义了SQL中使用的变量。 (建议使用支持预置语句的API,以防止SQL注入)。
// Same thing with some variable replacements // Here, a variable table name $table is backtick-quoted, and variables // in the VALUES list are single-quoted $query = "INSERT INTO `$table` (`id`, `col1`, `col2`, `date`) VALUES (NULL, '$val1', '$val2', '$date')";
使用准备好的语句时,请参考文档以确定是否必须引用语句的占位符。 PHP,PDO和MySQLi中最流行的API都包含未加引号的占位符,其他语言中的大多数准备好的语句API也是如此:
// PDO example with named parameters, unquoted
$query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`) VALUES (:id, :col1, :col2, :date)";
// MySQLi example with ? parameters, unquoted
$query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`) VALUES (?, ?, ?, ?)";
根据MySQL文档,您不需要使用以下字符集对标识符进行引号(backtick):
ASCII:[0-9,a-z,a-z$_]
(基本拉丁字母,数字0-9,美元,下划线)
您可以使用超出该集合的字符作为表或列标识符,例如,包括空格,但必须对它们进行引号(反勾号)。
MySQL中有两种类型的引号:
'
用于括住字符串文本`
用于封闭标识符,如表名和列名然后是“
,这是一种特殊情况。根据MySQL Server的sql_mode
:
“
字符可以像'
ANSI_QUOTES
模式中,“
字符可用于包围标识符,就像`
SELECT "column" FROM table WHERE foo = "bar"
查询将选择字符串文本“column”
,其中列foo
等于字符串“bar”
查询将选择列column
,其中列foo
等于列bar
“
,这样您的代码就独立于SQL模式
(上面有关于您的问题的SQL性质的很好的答案,但是如果您是PHP新手,这可能也是相关的。)
也许有必要提一下,PHP处理单引号和双引号字符串的方式是不同的。。。
单引号字符串是“文字”,几乎是所见即所得的字符串。 PHP对双引号字符串进行解释,以实现可能的变量替换(PHP中的反勾号并不完全是字符串;它们在shell中执行命令并返回结果)。
示例:
$foo = "bar";
echo 'there is a $foo'; // There is a $foo
echo "there is a $foo"; // There is a bar
echo `ls -l`; // ... a directory list