Search code examples
phpif-statementisset

Php if($var) used to work


I have som code for a website, that used to work fine with. I want to check if a variable or session is set. I used the following code:

if ($_GET['something']){ //Do something }

Now i try to install it on a local server, at i get a error code, saying that there is an undefined index.

It requires me to do:

if (isset($_GET['']) { //Do something }

Can i make a quick fix for this, as i don't want to change the code so many places?


Solution

  • You didn't get the error before, because your error_reporting and/or display_error settings were set too forgiving. Your first snippet is attempting to access a value in an array that might not exist. If it doesn't PHP always issues a notice.
    It's only after the notice has been issued that it can be hushed up (by turning off display_errors or setting error_reporting to not report notices (~E_NOTICE).

    You're asking for a quick fix:

    if (isset($_GET['something']))
    

    only requires you to add isset(). That's quick, and it fixes the issue. Besides: using isset is what you should do. Always.


    Off-topic, but perhaps useful:
    As I've explained in the comments: the best course of action for you now is to fix the issue itself, not ignoring the notices. To that end, a simple script that scans your projects directories for .php files (using glob), reads them in and looks for a pattern might prove useful:

    foreach ($phpFiles as $file)
    {
        $code = file_get_contents($file);//read the file
        if (preg_match_all('/if\s*\(\$[^[]+\[[^]]+\]\s*\)/',$code, $matches))
        {//find all usages of "if ($rawVar['offset'])" in code
            echo 'Expressions to check or fix in file: ', $file,':', PHP_EOL, '=>';
            echo implode(PHP_EOL.'=>', $matches[0]), PHP_EOL;
        }
    }
    

    run the script, perhaps write the output to a temp file, and set to work. The output should look something like:

    Expressions to check or fix in file: scriptname.php:
    => if ($_GET['something'])
    => if ($var[123])
    

    And so on. It's a workable format, and given time, you might be able to write a script for you to automatically refactor the code, too.
    Perhaps a more comprehensive (as in complete) regex to use here would be something like:

    /if\s*\((\|\||&&|\()?\$[^[]+\[[^]]+\]\s*(\|\||&&|\))?/
    

    But this, too, has some caveats still, but it's a start.


    Adding assignments - I'll do you one more favour: adding code that fixes the issues you get in assignment expressions like $var = $_GET['something'];. This can be done automatically, and quite easily, too:

    foreach ($phpFiles as $file)
    {
        $code = file_get_contents($file);//read the file
        $clean = preg_replace(
            '/(\$[^\s]+\s*={1}\s*)(\$[^[]+[^]]+\])\s*;/',
            '$1isset($2) ? $2 : null;',
            $code
        );
        file_put_contents($file, $clean);
    }
    

    I've tested this code like so:

    $code = '$foo = 123;
    $foo = $_GET["bar"];';
    $clean = preg_replace(
        '/(\$[^\s]+\s*={1}\s*)(\$[^[]+[^]]+\])\s*;/',
        '$1isset($2) ? $2 : null;',
        $code
    );
    echo $clean, PHP_EOL;
    

    And it yielded the expected output:

    $foo = 123;
    $foo = isset($_GET["bar"]) ? $_GET["bar"] : null;
    

    Combine these two regex's and you should be well on your way to refactoring the code you have...