Intuitive dependency management with code includes?

I am building a PHP CMS system that parses template files and replaces tags with content. Sometimes this content is a HTML, CSS or JS snippet, but it can also be a code include. Most code includes use dependencies, already set in the main scope: the app class, where the start() function resides and all needed domain objects are loaded. Some of these objects are: site, URL, page, etc.. The PHP scripts are included in a different scope, so I am can't access the dependencies the way I want -> from the app class. I am thinking about Dependency Injection using a dependency container class, but of course, this is not visible when working inside an include. How do I keep the dependencies accessible in an intuitive way? Code example: class app { protected $dependencyContainer; function __construct() { $this->dependencyContainer = new dependencyContainer(); } // Called by index.php public function start() { // Load in navigator that contains routing information $this->dependencyContainer->set('navigator', new navigator($_SERVER['REQUEST_URI'], $_SERVER['HTTP_HOST'])); // Load site data $domainController = new domainController(); $site = $domainController->loadSite($this->dependencyContainer->get('navigator')); $this->dependencyContainer->set('site', $site); $pageController = new pageController(); $page = $pageController->loadPage($this->dependencyContainer->get('navigator')); $this->dependencyContainer->set('page', $page); // Etc... // Etc... $templatePath = $site->getTemplate(); $this->renderDocument($templatePath); } private function renderDocument($templatePath) { $template = file_get_contents($templatePath); $lines = explode("\n", $template); foreach($lines as $line) { // If a tag is found, the dependencies are asked if it contains data for this if($tag = $this->filter($line)) { $fragments = $this->dependencyContainer->output($tag); foreach($fragment as $fragment) { if($fragment->needDependencies()) { // AT THIS POINT I TRAVERSE INTO AN OBJECT AND // INCLUDE A PHP SCRIPT $fragment->render($this->dependencyContainer); } else { $fragment->render(); } } // Process lines, echo the ones that are plain HTML } else { echo $line; } } } } The fragment object that the dependencies are passed to: class dependencyFragment { protected $data; const NEEDSDEPENDENCIES = true; // THIS IS THE LOCAL SCOPE OF THE INCLUDE: public function render($dependencies) { return include __PATH__ . $this->data; } } A script file that gets included:

Feb 6, 2025 - 03:24
 0
Intuitive dependency management with code includes?

I am building a PHP CMS system that parses template files and replaces tags with content. Sometimes this content is a HTML, CSS or JS snippet, but it can also be a code include.

Most code includes use dependencies, already set in the main scope: the app class, where the start() function resides and all needed domain objects are loaded. Some of these objects are: site, URL, page, etc..

The PHP scripts are included in a different scope, so I am can't access the dependencies the way I want -> from the app class.

I am thinking about Dependency Injection using a dependency container class, but of course, this is not visible when working inside an include.

How do I keep the dependencies accessible in an intuitive way?

Code example:

class app {

    protected $dependencyContainer;

    function __construct() {
        $this->dependencyContainer = new dependencyContainer();
    }

    // Called by index.php
    public function start() {

        // Load in navigator that contains routing information
        $this->dependencyContainer->set('navigator', new navigator($_SERVER['REQUEST_URI'], $_SERVER['HTTP_HOST']));

        // Load site data 
        $domainController = new domainController();
        $site = $domainController->loadSite($this->dependencyContainer->get('navigator'));
        $this->dependencyContainer->set('site', $site);

        $pageController = new pageController();
        $page = $pageController->loadPage($this->dependencyContainer->get('navigator'));
        $this->dependencyContainer->set('page', $page);

        // Etc...
        // Etc...

        $templatePath = $site->getTemplate();
        $this->renderDocument($templatePath);
    }

    private function renderDocument($templatePath) {       
        $template = file_get_contents($templatePath);

        $lines = explode("\n", $template);

        foreach($lines as $line) {                    
            // If a tag is found, the dependencies are asked if it contains data for this 
            if($tag = $this->filter($line)) {
                $fragments = $this->dependencyContainer->output($tag);

                foreach($fragment as $fragment) {
                    if($fragment->needDependencies()) {


                        // AT THIS POINT I TRAVERSE INTO AN OBJECT AND 
                        // INCLUDE A PHP SCRIPT

                        $fragment->render($this->dependencyContainer);
                    } else {
                        $fragment->render();
                    }
                }
            // Process lines, echo the ones that are plain HTML
            } else {
                echo $line;
            }
         }
    }
}

The fragment object that the dependencies are passed to:

class dependencyFragment {
    protected $data;
    const NEEDSDEPENDENCIES = true;

    // THIS IS THE LOCAL SCOPE OF THE INCLUDE:
    public function render($dependencies) {
        return include __PATH__ . $this->data;
    }
}

A script file that gets included:

get('page')...

I have the feeling this is very hard to understand without first understanding how and where the dependencies are set and injected?

Is this usual way to go?