Search code examples
phpvariable-variables

What was the reason to use "@$$var = .. " in this PHP code?


I have some code that returns error Undefined variable: dblink:

This code is from a legacy system. "dblink" variable appears only inside this function in this one file.

function db_connect($dbhost, $dbuser, $dbpass, $dbname = "") {
    if (!strlen($dbuser) || !strlen($dbpass) || !strlen($dbhost))
        return null;

    @$$dblink = mysql_connect($dbhost, $dbuser, $dbpass);
    if ($$dblink && $dbname)
        @mysql_select_db($dbname);
    //set desired encoding just in case mysql charset is not UTF-8
    if ($$dblink) {
        @mysql_query('SET NAMES "UTF8"');
        @mysql_query('SET COLLATION_CONNECTION=utf8_general_ci');
    }
    return $$dblink;
}

I am not entirely sure what to make of @$$variable and $$variable. I assume that @ means "suppress warnings", and "$$variable" just means "${value of $variable}", which does not make sense.

I am planning to rename this to just $dblink and see what happens. There may possibly be a historical reason for this in earlier PHP versions, or maybe at one time such code did make sense, and the answer to how it made sense is what my question is seeking.


Solution

  • It's clearly wrong, but will still work:

    $$foo = 'bar';
    echo $foo; // Returns nothing
    echo $$foo; // Returns bar
    echo $$otherUndefinedVar; // Returns bar
    echo ${''}; // Returns bar
    echo ${NULL}; // Returns bar
    if ($$foo) echo 'true'; // Returns true
    

    This is because PHP will just use the default value of an empty string (in the context of string-based functionality) while throwing a notice that $foo is undefined, then you're essentially working with a variable named $ (but you can't access it without using ${''}.)

    And since there was a notice being thrown, I bet this previous developer used @ to suppress the notice without questioning why the usage of $$ didn't work. But I'm not psychic!

    Unfortunately I can't answer your question since it's too broad (and like I mentioned, not a psychic ;), but hopefully the code example above gives some clarity as to why it still worked - it's a common problem for amateur programmers to "beat the code up" until it works the way they want to. Often making very very bad mistakes in the process.