使用phpass生成哈希,生成以下字符串:
$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi
然后是标准查询:
"INSERT INTO su_auth (
AuthAlias, AuthUsername,
AuthPass,
AuthSessionID, AuthIP, AuthUserAgent
)
VALUES (
'Me', 'Myself',
'$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi',
NULL, NULL, NULL
)"
当部分$KHiiru4yzYh141GUh2xIMew
被视为空变量并作为空变量(即空值)提交时,会出现问题。因此存储的字符串是:$2a$08//bCc7rxMuY1rtDApwA66/czIiurLi
。在$
前面放一个反斜杠,但显然是不可行的。
为什么在带引号的字符串中会发生这种情况?为什么前面的$
没有引发同样的反应?我能做些什么来预防呢?
您看到您所看到的原因是因为您使用了双引号字符串的查询。在PHP中,单引号字符串由PHP解释。因此,在您的情况下,PHP读取查询并看到一个变量$KHiiru4yzYh141GUh2xIMew
。
这个变量从来没有明显设置过,因此会出现一个通知:
注意:未定义变量:KHiiru4yzYh141GUh2xIMew in…
和将导致null
(同样是因为从未设置该变量)。
要了解PHP如何读取字符串,请参阅这个解释页。
现在回答你的问题,为什么其他$
不被解释为变量。这与PHP变量不以数字开头的事实有关。所以PHP知道$2
永远不能是一个变量。
PHP中有效的变量名如下:
[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*
在PHP中有一种方法可以让变量以数字开头:${'2a'} = 'foo';
所以你有四个选择来修复你的代码:
使用单引号
'INSERT INTO su_auth (
AuthAlias, AuthUsername, AuthPass, AuthSessionID, AuthIP, AuthUserAgent
) VALUES (
'Me',
'Myself',
'$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi',
NULL, NULL, NULL
)'
连接
"INSERT INTO su_auth (
AuthAlias, AuthUsername, AuthPass, AuthSessionID, AuthIP, AuthUserAgent
) VALUES (
'Me',
'Myself',
'". '$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi' . "',
NULL, NULL, NULL
)"
sprintf
echo sprintf("INSERT INTO su_auth (AuthAlias, AuthUsername, AuthPass, AuthSessionID, AuthIP, AuthUserAgent) VALUES ('Me', 'Myself', '%s', null, null, null)", '$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi');
为什么在查询中直接使用你的数据?使用带绑定参数的预处理语句
$stmt = $connection->prepare('INSERT INTO su_auth (AuthAlias, AuthUsername, AuthPass, AuthSessionID, AuthIP, AuthUserAgent) VALUES (:AuthAlias, :AuthUsername, :AuthPass, :AuthSessionID, :AuthIP, :AuthUserAgent)');
$stmt->execute([
'AuthAlias' => 'Me',
'AuthUsername' => 'Myself',
'AuthPass' => '$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi',
'AuthSessionID' => null,
'AuthIP' => null,
'AuthUserAgent' => null,
]);