M
M
maxcad2021-01-10 00:32:10
PHP
maxcad, 2021-01-10 00:32:10

How to avoid repetition of includes in OOP PHP?

In almost every site engine, the config.php file lies at the root.
Clearly, this is so that any class can cling data from this file. But a question arises. And how to make the data of this file global? To avoid including config.php every time a new class is declared?

For example:

class class1 {

    function __construct() {
        include 'config.php';
    }
}

class class2 {

    function __construct() {
        include 'config.php';
    }
}


This approach doesn't seem right to me.

Passing it as a parameter to the class also seems not a very good solution:

include 'config.php';

class class1 {
    function __construct($config) {
        code;
    }
}


class class2 {
    function __construct($config) {
        code;
    }
}


Even if you create a config class and declare it inside other classes, the include will still be repeated.

class config {

    function __construct() {
        include 'config.php';
    }
}


class class1 {
    function __construct() {
        $config = new config;
    }
}

class class2 {
    function __construct() {
        $config = new config;
    }
}


As I understand it, in such constructions, the include_once function will still not work, since each call to 'config.php' is isolated inside the class.

Well, making all other classes the heirs of the config class also seems bad manners.

How is the data extraction from 'config.php' implemented in the site engines?
In config.php, a simple non-global array is usually declared and its variables are not available inside classes. That's why they don't use $GLOBALS either.
Do they really include it every time some class needs it?

Answer the question

In order to leave comments, you need to log in

5 answer(s)
A
Andrey Ezhgurov, 2021-01-10
@maxcad

Firstly, no one includes files in modern code - many years ago, https://www.php.net/manual/ru/language.oop5.autolo... was invented to automatically load classes . And in the entire code of the site there are 2-3 include, one of which is inside the autoloader generated by composer.
Secondly, all modern frameworks have a single entry point: the index.php file, to which all requests to the site are passed. In this file, the config is connected, and the framework is initialized. After that, control is transferred to the router, which parses the request URL and transfers control to the desired controller class.
Thirdly, to automatically create objects with automatic transfer of the necessary data (including configuration) to the constructor and avoid duplication of created objects, dependency injection (DI) containers were invented a long time ago https://elisdn.ru/blog/116/psr7- framework-container (I advise you to watch all the lessons in this cycle).

F
FanatPHP, 2021-01-10
@FanatPHP

Of all the nonsense that has already been written here, and more will be written by self-styled "curators" and experts, the only useful answer is Andrei Yezhgurov.
But it answers your next question.
And the answer to the current one is

Pass it to the class as a parameter

This is the only correct practice, even if it seems to you not a very good solution.
Only not the whole config, but only those options that this class needs.
This is how OOP actually works. To consolidate the material, you can read about dependency injection.

R
Roman Sarvarov, 2021-01-10
@megakor

The easiest option.

class Config {
    private static $configData;

    public static function get($parameter = null, $default = null)
    {
        if (is_null(self::$configData)) {
            self::$configData = include '../config.php';
        }

        if ($parameter) {
            return self::$configData[$parameter] ?? $default;
        }

        return self::$configData;
    }
}

// в клиентском методе
public function someMethod() {
    $config = Config::get();
}

<?php 
// в config.php
return [
    'param' => 'value',
];
?>

I
Ivan Shumov, 2021-01-10
@inoise

It is worth reading about namespaces and composer and really stop writing shit code

S
Sergey delphinpro, 2021-01-10
@delphinpro

We are writing a service for working with settings. You can call it - Config.
We inject it into each controller or into the base controller from which others are inherited. Manually or using the DI manager.
As a result, access to the settings looks something like this

class BaseController {
  protected $config;
  public function __contruct(Config $config){
    $this->config = $config;
  }
}

class MyController extends BaseController {
  public function myMethod() {
    $var = $this->config->get('someSetting');
  }
}

You can make a helper function that will resolve the service from the di-container and return it . Simplifying, you can forget about all these terrible words about dependency injection, and just write a function that is available everywhere.
config()->get('someSetting');
config()

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question