Search code examples
phpfunctionglobal-variables

PHP global variable is null inside a function, but is not null outside it


I've run into an error, where global seems to not work properly and can't access variable.

Here's my code:

function getComments($id)
{
    global $conn;
    $COMPONENT_NAME = "view_company_comments";
    include_once "validateUser.php";

Just for context, if COMPONENT_NAME isn't going to be present in some defined list, script execution will stop using die() function.

Now inside "validateUser.php":

(explained everything in comments)

   <?php

   if (!isset($COMPONENT_NAME)) {
        die(json_encode(["error" => "validating user: component was not set."]));
    } else {

        include_once "permissions.php";
        $validateUser_allowedActions = permissionsInitActions();

        //So far in, var_dump($COMPONENT_NAME) works properly here, and I get the component name succesfully. 
        //But watch next:

        //"permissionsAllowed()" is a function from "permissions.php", 
        //this function returns "false" here, expected result is "true"

        if (!permissionsAllowed($validateUser_allowedActions)) {
            die(json_encode(["error" => $COMPONENT_NAME . ": Unvalidated user privillege."]));
        }
    }

And inside "permissions.php":

function permissionsAllowed($actions)
{
    global $COMPONENT_NAME, $conn;

    //Here, var_dump($COMPONENT_NAME) results to "null", which is weird
    //because in "validateUser.php" it is a correct string value.

    $sql = "SELECT id FROM permission_actions WHERE `name` = '$COMPONENT_NAME'";
    $result = mysqli_query($conn, $sql);
    $actionID = mysqli_fetch_assoc($result)["id"];
    var_dump($COMPONENT_NAME);

    if (in_array($actionID, $actions)) {
        return true;
    }
    return false;
}

What is happening here? What am I missing?

Thanks for any help.


Solution

  • $COMPONENT_NAME is not a global variable in getComments. Although you have declared it global in permissionsAllowed, it is not declared global in getComments and thus $COMPONENT_NAME in getComments is local to that scope and hence not visible via global $COMPONENT_NAME in permissionsAllowed.

    Consider the following code (demo):

    $b = 5;
    
    function f1 () {
        global $a;
        $a = 4;
        $b = 3;
        $c = 2;
        f2();
    }
    
    function f2 () {
        global $a, $b, $c;
        var_dump($a);
        var_dump($b);
        var_dump($c);
    }
    
    f1();
    

    Output:

    int(4)
    int(5)
    NULL
    

    $a is not declared at the top level but is declared global in f1 and f2 - modifications made to it in f1 can be seen in f2.
    $b is declared at the top level, but only global in f2. $b in f1 is local to that scope and changes to it have no effect on $b in f2.
    $c is not declared at the top level and is only global in f2. Again, $c in f1 is local to that scope and changes to it have no effect on $c in f2, so the global $c that is referred to in f2 has no value (null) since it is not set anywhere.