3

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?

Julio María Meca Hansen
  • 1,303
  • 1
  • 17
  • 37
  • 1
    Are you sure this `include_once` is called exactly once? What if you already included it somewhere else? For that kind of things, when you want to return a bunch of data from some file, I'd recommend to use `require`. – ksimka Mar 21 '16 at 12:44
  • I'll have to double check after reading all your comments, but this controller is loaded only when any given user tries to access the backend (and is redirected to the login screen if his/her session data is not found) and it's not shared in any other part of the backend or frontend. – Julio María Meca Hansen Mar 21 '16 at 13:37

1 Answers1

1

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.

Philipp
  • 15,377
  • 4
  • 35
  • 52