views:

280

answers:

6

Spent some time troubleshooting a problem whereby a PHP/MySQL web application was having problems connecting to the database. The database could be accessed from the shell and phpMyAdmin with the exact same credentials and it didn't make sense.

Turns out the password had a $ sign in it:

$_DB["password"] = "mypas$word";

The password being sent was "mypas" which is obviously wrong.

What's the best way to handle this problem? I escaped the $ with a \

$_DB["password"] = "mypas\$word";

and it worked.

I generally use $string = 'test' for strings which is probably how I avoided running into this before.

Is this correct behavior? What if this password was stored in a database and PHP pulled it out - would this same problem occur? What am I missing here...

+2  A: 

Just put it in a single-quoted string:

$_DB['password'] = 'mypas$word';

The double-quoted string will interpolate variables, but single-quoted strings won't. So that will solve your problem.

Ray Hidayat
+2  A: 

use single quotes

$_DB["password"] = 'mypas$word';
ghostdog74
+14  A: 
$_DB['password'] = 'mypas$word';

Single quote strings are not processed and are taken "as-is". You should always use single quote strings unless you specifically need the $variable or escape sequences (\n, \r, etc) substitutions. It's faster and less error prone.

Andreas Bonini
Thanks for your answer. It appears this is a problem of best practice. With strict error reporting this may have been picked up faster. From my original question - could this be an issue when grabbing passwords from the database, or will PHP escape the $ sign?
ncatnow
@ncatnow: it can't be an issue because the substitutions is only done in double quoted strings ("string"). When you read a string from the database it is read internally by PHP so you're not using the double quoted strings to set it (or even the single quote ones). Imagine the compiler replacing all the $stuff **right before** setting the variable.
Andreas Bonini
It's only an issue for strings written out directly in your source code, using double quotes. They must physically appear `"like $this"` in a `.php` source file. Strings from the database, from a file, from the user, etc., are not subject to interpolation.
John Kugelman
+1  A: 

Just use single quotes ' instead of " and it will not try and treat $word as a variable.

$_DB['password'] = 'mypas$word';
Jeff Beck
+1  A: 

Strings quotes with the double quotation are interpreted for variables. Single quoted strings are interpreted literally.

$a = "one";
$b = "$a";
echo $b . "\n";
$b = '$a';
echo $b . "\n";

This should yield:

one
$a
Brian Riehman
+4  A: 

PHP is interpolating the variable $word into the string mypas$word, as is normal behaviour for string literals delineated with double quotes. Since $word is presumably undefined, the resulting interpolated string is mypas.

The solution is to use single quotes. Single-quoted string literals do not undergo variable interpolation.

Benji XVI