phpvariablesnamespacesinclude-once

PHP - variable inclusion not working with include_once inside a namespace


I'm modelling a login page using different schemas (basic username & password combination and another schema using a Yubikey, for now).

My controller looks like this:

namespace Document {
    /**
     * get the current authentication schema
     */
    $schema = \Modules\Backend\Authentication::getSchema();

    /**
     * initialize the template data
     */
    if (empty($data)) {
        $data = [];
    }

    /**
     * include the document content block
     */
    $data = array_merge_recursive($data, [
        "document" => [
            "sections" => [
                /* further content goes here */
            ]
        ]
    ]);

    /**
     * include the authentication schema content block
     */
    if (file_exists($schema = "{$_SERVER["DOCUMENT_ROOT"]}/pages/controllers/backend/login/{$schema}.php")) {
        include_once($schema);
    }

    /**
     * output the document content
     */
    echo \Helpers\Templates::getTemplate("backend/pages/login", $data);

    /**
     * free all used resources
     */
    unset($data, $schema);
}

The authentication schema looks like this:

/**
 * include the document content block
 */
$data = array_merge_recursive(!empty($data) ? $data : [], [
    "document" => [
        "sections" => [
            "schema" => [
                "content" => [
                    "token" => \Helpers\Strings::getToken(),
                    /* rest of content block goes here */
                ],
                "strings" => [
                    "title" => _("This is a sample string"),
                    /* rest of translation strings block goes here */
                ]
            ]
        ]
    ]
]);

The problem I have is include_once() is not working for me, as the $data variable isn't really seen neither by the authentication schema nor the opposite (the document namespace seeing any content coming from the authentication schema on inclusion).

However, if I use include() it works. Maybe the problem lies within the use of a namespace and including external content. I never use the include() function as I always like to check if the script is already included, even if it has bit of a performance penalty for the extra check.

Maybe I'm not fully understanding how namespaces work in PHP or I did something weird with the array_merge_recursive() function, but the more I look at the code, the less I find about something potentially wrong and I feel a bit lost.

Can anyone help me figuring this?


Solution

  • A simple setup of your script, showed, include_once inside namespaces acually worked the same as include. So it seems, you included schema.php somewhere else before.

    <?php
    
    namespace Document {
        include_once "data.php";
    
        echo "Hello " . $data;
    }
    

    data.php

    <?php
    
    $data = "World";
    

    In your case, you could add some debug output, to get the file/line, which included your scheme the first time. I.e.

    var_dump(array_map(function($x) {
        return [$x['file'], $x['line']];
    }, debug_backtrace()));
    

    But I would recommed, to just use include instead of include_once and return the data, instead of creating new vars.

    I.e. scheme.php

    return [
        "document" => [
            "sections" => [
                "schema" => [
                    "content" => [
                        "token" => \Helpers\Strings::getToken(),
                        /* rest of content block goes here */
                    ],
                    "strings" => [
                        "title" => _("This is a sample string"),
                        /* rest of translation strings block goes here */
                    ]
                ]
            ]
        ]
    ];
    

    and later include it with

    $data = include($schema . '.php");
    

    and do your merging (and other stuff) where you need it.