Чому об’єкт створюється два рази
@DubecZ нууу. я сподівався ви не попросите.
1) почнемо з автозавантаження класів. Чому б її не використати? Є стандарти, PSR-0 / PSR-4 які описують як що має працювати і т.д. Є готові Автозавантажувач, можна скористатися composer, можна для PSR-0 зробити свій в кілька рядків і більше ніколи не страждати цієї фігньою з require_once / require.
2) у вас клас Core чомусь успадковується від класу Settings, що як би не логічно. Логічно було б клас Settings передавати в конструктор Core. Так навіть якщо і залишити все як є, чому в файлі містить Core-клас нету підключення з файлом класу сеттінгом? воно там як би потрібніше. І ми знову ж повертаємося до питання автозавантаження класів, з нею було б симпатичніше вже
3) робити коннект до бази в конструкторі погана ідея. Взагалі робити щось крім ініціалізації ДАНИХ в конструкторі погана затія. Найпростіший випадок, ми створили інстанси, він підключився до бази, але нам і не потрібно було лестощі в базу і в результаті у нас досить багато часу Сьело підключення в нікому не потрібною базі даних. Ліниве підключення набагато краще в цьому плані
4) Є така штука як принцип єдиної відповідальності. По ньому, клас повинен вміти робити тільки щось одне. Якщо у вас один і той же клас відповідає за роботу з базою і логування, вже щось пішло не так. Згідно з цим принципом, у нас повинна бути тільки одна причина поміняти щось в реалізації класу. А тут у нас їх дві - переробити роботу з базою і обробка логів
Набагато краще в цьому ключі зробити окремо клас для роботи з BD та клас для логування і передавати їх в конструктор класу
5) чому б раутінг так само не винести в компонент який? Було б зручніше. А ще краще - скористатися готовим компонентом, хоча я сподіваюся що цей код ви пишіть виключно в освітніх цілях і в продакшен він ніколи не потрапить. Якщо це так, то тоді свій велосипед можна і потрібно писати, але слід виносити все це справа в окремий компонент, який буде ресолвіть який контролер смикати.
6) Якщо ви виконали всі пункти вище, у вас може виникнути думка що якось не зручно працювати з такою купою різних класів. І тут ви матимете рацію, тому придумали такі штуки як контейнери залежностей, сервіс-локатори і т.д. Ці штуки виникають знову ж з принципу єдиної відповідальності і інверсії залежностей. У вас повинен бути компонент, який вміє збирати інші компоненти і тільки це він і буде робити. Ви у нього просите $ container-> get ( 'db') а воно або створюєте вам інстанси класу DB або видає раніше створений. Причому реєстрацію всіх цих штук можна винести в файл і там робити якось так:
фух. Якщо вам здається що все це зайвий оверхед, то так. Може так здатися. Але слід привчати себе робити все саме так що б потім при збільшенні складності проектів не писати говнокод.