Как избежать повтора инклюдов в ООП PHP?

Практически в каждом движке сайта в корне лежит файл config.php
Понятно, это для того чтобы любой класс мог цеплять данные из этого файла. Но возникает вопрос. А как сделать данные этого файла глобальными? Чтобы при не инклюдить config.php каждый раз как объявляется новый класс?

Например:
class class1 {

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

class class2 {

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


Такой подход мне кажется не очень правильным.

Передавать его в класс параметром тоже кажется не очень хорошим решением:

include 'config.php';

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


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


Даже если создать класс config и объявлять его внутри других классов то инклюд все равно будет повторяться.

class config {

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


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

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


Я так понимаю в таких конструкциях функция include_once все равно не сработает так как каждый вызов 'config.php' изолирован внутри класса.

Ну и сделать все остальные классы наследниками класса config тоже кажется моветоном.

Как же в движках сайта реализовано извлечение данных из 'config.php'?
В config.php обычно объявлен простой не глобальный массив и его переменные не доступны внутри классов. Поэтому $GLOBALS они тоже не используют.
Неужели они его инклюдят каждый раз когда он понадобится какому нибудь классу?
  • Вопрос задан
  • 915 просмотров
Решения вопроса 1
@eandr_67
web-программист (*AMP, Go, JavaScript, вёрстка).
Во первых, в современном коде файлы никто не инклюдит - много лет назад для автоматической загрузки классов придумали https://www.php.net/manual/ru/language.oop5.autolo.... И во всём коде сайта остаётся 2-3 include, один из которых - внутри генрируемого composer'ом автозагрузчика.

Во вторых, все современные фреймворки имеют единственную точку входа: файл index.php, которому передаются все обращения к сайту. В этом файле производятся подключение конфига, и инициализация фреймворка. После чего управление передаётся роутеру, который разбирает URL запроса и передаёт управление нужному классу-контроллеру.

В третьих, для автоматического создания объектов с автоматической же передачей конструктору нужных данных (в том числе и конфигурации) и исключения дублирования создаваемых объектов давным-давно придумали контейнеры внедрения зависимостей (DI) https://elisdn.ru/blog/116/psr7-framework-container (советую посмотреть все уроки этого цикла).
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
FanatPHP
@FanatPHP
Чебуратор тега РНР
Из всей той ерунды, которую тут уже успели понаписать, и ещё понапишут самозваные "кураторы" и эксперты, единственно полезным является ответ Андрей Ежгуров
Но он отвечает на следующий твой вопрос.

А ответом на текущий является

Передавать его в класс параметром

Это единственно правильная практика, пусть она даже и кажется тебе не очень хорошим решением.
Только не целиком конфиг а лишь те опции, которые нужны данному классу.
Это то как на самом деле работает ООП. Для закрепления материала можешь почитать про dependency injection.
Ответ написан
megakor
@megakor
Go/PHP developer | ВКонтакте
Самый простой вариант.

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',
];
?>
Ответ написан
inoise
@inoise Куратор тега PHP
Solution Architect, AWS Certified, Serverless
Стоит почитать про namespaces и composer и действительно перестать писать говнокод
Ответ написан
delphinpro
@delphinpro Куратор тега PHP
frontend developer
Пишем некий сервис для работы с настройками. Можно так и назвать - Config.
Инжектим его в каждый контроллер или в базовый контроллер, от которого наследуются другие. Вручную или используя менеджер DI.
В итоге доступ к настройкам выглядит как-тот так

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

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


Докучи можно сделать функцию-хелпер, которая будет резолвить сервис из di-контейнера и возвращать его

config()->get('someSetting');

Упрощая, можно забить на все эти страшные слова про внедрение зависимостей, и просто написать функцию config(), доступную везде.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы