Hashed密码的部分被MySQL看作变量

时间:2014-05-03 12:28:35

标签: php mysql phpass

使用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。在$之前放置一个反斜杠,但显然不可行。

为什么会在带引号的字符串中发生?为什么前面的$不会触发相同的反应?我该怎么做才能阻止它?

1 个答案:

答案 0 :(得分:1)

您看到所见内容的原因是您使用double quoted string进行查询。在PHP中,单引号字符串由PHP解释。那么在你的情况下发生的是PHP读取查询并看到变量$KHiiru4yzYh141GUh2xIMew

这个变量从未明确设置,因为suck会产生通知:

  

注意:未定义的变量:KHiiru4yzYh141GUh2xIMew in ...

并且会导致null(再次因为变量从未设置)。

要了解PHP如何读取字符串,请参阅此explain page

现在回答你的问题为什么其他$没有被解释为变量。这与PHP变量不以数字开头的事实有关。所以PHP知道$2永远不可能是变量。

PHP look like中的有效变量名称:

[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');

您为什么在您的查询中直接使用您的数据? Use prepared statements with bound parameters

$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,
]);

选项四是首选。