Domanda

Using phpass to generate hashes, the following string is generated:

$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi

Then a standard query:

"INSERT INTO su_auth ( 
                      AuthAlias, AuthUsername, 
                      AuthPass, 
                      AuthSessionID, AuthIP, AuthUserAgent
                    )
                    VALUES ( 
                      'Me', 'Myself',         
                      '$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi', 
                       NULL, NULL, NULL
                    )"

A problem arises when the portion $KHiiru4yzYh141GUh2xIMew is viewed as an empty variable and submitted as such (i.e. a null value). The stored string is therefore: $2a$08//bCc7rxMuY1rtDApwA66/czIiurLi. Placing a backslash before the $ works, but is obviously not feasible.

Why does this happen within a quoted string? Why do the preceding $'s not trigger the same reaction? What can I do to prevent it?

È stato utile?

Soluzione

The reason why you are seeing what you are seeing is because you use a double quoted string for the query. In PHP single quoted string are interpreted by PHP. So what happens in your case is that PHP reads the query and sees a variable $KHiiru4yzYh141GUh2xIMew.

This variable is never set obviously and as suck results in a notice:

Notice: Undefined variable: KHiiru4yzYh141GUh2xIMew in...

And will result in null (again because the variable is never set).

To see how PHP reads the string see this explain page.

Now to answer your question why the other $ are not being interpreted as variables. This has to do with the fact that PHP variables don't start with a number. So PHP knows $2 can never be a variable.

Valid variable names in PHP look like:

[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

There is a way to let a variable start with a number in PHP though: ${'2a'} = 'foo';

So you have four choices to fix your code:

Use single quotes

'INSERT INTO su_auth ( 
     AuthAlias, AuthUsername, AuthPass, AuthSessionID, AuthIP, AuthUserAgent
 ) VALUES ( 
     \'Me\',
     \'Myself\',                                  
     \'$2a$08$KHiiru4yzYh141GUh2xIMew//bCc7rxMuY1rtDApwA66/czIiurLi\', 
     NULL, NULL, NULL
 )'

Concatenate

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

WHY ARE YOU USING YOUR DATA DIRECTLY IN YOUR QUERY??? 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,
]);

Option four would be preferred.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top