Как лучше организовать код?
=============================

 Разрабатываю проекты на php, которые становятся все больше. При разработке нового проекта я столкнулся с проблемой - организацией кода в проекте, логики и т.д.  
  

Кратко опишу мой проект и его структуру. Опишу образно и упрощенно.  

Проект разделен на модули, каждый из которых выполняет свои задачи. Модуль - это отдельный проект (папка с файлами). для каждого модуля создана своя БД с именем этого модуля, содержащая таблицы, используемые при работе этого модуля.  
  

Примеры модулей  

Модуль статистики - собирает статистику.   

Модуль отображения - выводит графики на экран.  

Это только пара из множества модулей.  
  

Важно обеспечить стабильность работы системы. А также независимость работы модулей.  

Например, чтобы при удалении модуля статистики, модуль отображения оставался работоспособным.  

(С учетом того, что он не использует модуль статистики, например его данные. )  
  

Полная независимость модулей друг от друга не рациональна т.к. они используют общие файлы, общие функции (js билиотеки, css и т.д.). Например - для каждого модуля нужна проверка авторизации пользователя.  

Значит нужна функция. Где её писать? Как организовать структуру?  
  

Я руководствуюсь следующей логикой. Так как это общая функция т.е. будет использоваться во многих модулях, то создаю папку common.  

Так как эта функция связана с безопасностью, то создаю файл security\_functions.php. И там пишу функцию.  

Итого имею файл common/security\_functions.php и подключаю его во все модули.  
  

Хорошо. Но теперь мне надо создать систему логирования. Чтобы знать, если вдруг пользователь не смог войти в систему (подбор пароля). По аналогии пишу функцию. Итого имею второй файл common/log\_functions.php  
  

Также мне надо работать с данными. Например создать массив с кодами ошибок. Которые будут использованы в системе логирования.  
  

И вот тут уже возникает проблема. Новая предполагаемая функция будет работать и с данными и с безопасностью. Там будут и коды событий и коды ошибок. Куда её писать? В какой файл?  

С другой стороны и функция логирования тоже связана с безопасностью. Она может писать и стандартные события (любые) и события неудачных попыток входа.  
  

Разделение функций по назначению становится сомнительным. Особенно при огромном их числе.  

Система многофункциональная у неё много задач и просто так разделить функции у меня не выходит.  

Писать всё в один файл и подключать его ко всем модулям - создавать риск одной ошибкой сломать всю систему. Писать куда попало - плохо с организационной точки зрения.  
  

Создавать 10 файлов с функциями (в которых есть и пространства имен), подключать их к модулю (или часть файлов), а потом использовать тоже затруднительно. Иногда просто забываешь а в каком файле у тебя эта функция. Ты не видишь их всех, "бегаешь по файлам".  
  

Помимо этой проблемы, возникает ещё проблема взаимосвязи с БД.   

Каждый модуль выполняет свои задачи. И для своих задач он использует свою БД, со своими таблицами.   
  

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

Возникает множество логических противоречий. Деление функций по задачам, назначению затруднительно, при их большом количестве. Деление по модулям (эти функции только используем в этом файле с этой бд) невозможно в силу того, что часть из них повторяются. Проще говоря общие - и дублировать их в каждом модуле нет смысла. Деление функций по БД - эта функция принадлежит этому модулю т.к. для него используется эта БД тоже невозможно т.к. функции могут использовать разные БД.  
  

Надеюсь поняли о чем я говорю. Хотя это сложно, понять этот текст.)  

Проще - система состоит из кучи всего и это всё крайне взаимосвязано. А надо устранить большинство связей, разложить всё по полочкам, по категориям для удобной разработки и поиска ошибок.  
  

Как лучше организовать код? Предложения? 

 У меня сложилось впечатление, что вы изобрели велосипед.  

В общем-то в вашем тексте много разумных находок и выводов.   

Однако может вам имеет смысл выбрать какой-то фреймворк? Yii, Laravel, Symfony и т.п.  

Вы автоматом получите и структуру, и порядок работы, и разделение и кучу всего, что упростило бы вам жизнь. М? 

 Во первых - ООП, иначе нет смысла заморачиваться с крупным проектом, да и функциональный подход сегодня вообще в проектах больше чем "свой микроблог" никто не использует, это не рационально.  

Так же откройте для себя MVC и возьмите какой-то фреймворк в котором все это уже нормально реализовано, в итоге время потраченное на прочтение документации и написание контроллеров и моделей к проекту будет в разы меньше чем вы потратите на свое кошмарное велосипедостроение. Кроме того, построенный по вашим наброскам Титаник и показать то кому-либо будет стыдно, а знания любого современного фреймворка напротив - будет большим плюсом.  

> Удалив модуль и БД мы повлияем на работу других модулей. Изменив структуру БД мы повлияем на работу других модулей.

SOLID, DRY, KISS...PSR4 и много других страшных аббривиатур вам помогут ) 

 На TS есть фреймворк, называется Nest. Он изначально использует модульную структуру, и там она реализована достаточно хорошо. Гляньте.  
  

Далее как я делаю в Laravel проекте:  

- /vendor - зависимости компоузера, в виде сторонних библиотек и компонентов symfony/laravel. Там есть весь базовый функционал, как, например, работа с БД. Такие зависимости в любом случае будут тесно связанны с логикой приложения, и думать об их удалении не стоит вообще. Максимум, что вы можете - построить слой абстракции над /vendor, но это ПЛОХАЯ идея.  

- /app/Ship - увидел это в другом фреймворке, называется Apiato. Сам по себе он хрень, но сама идея мне понравилась. Этот "корабль" - слой твиков, временных фиксов, загрузчиков и другого, что касается каких-то базовых, недостающий частей фреймворка/библиотек, и используется всемя модулями в проекте. Например:  
* загрузка модулей. Так как для laravel нету нормальной системы, пришлось написать свой костыльчик. Лежит он в ship.
* обработчик исключений
* ядра (хттп и консольное)
* твики для миграций
* общие трейты, скоупы
* миксины
* общие миддлвейры

  
  

В общем все то, что относится ко всему проекту в целому. Структура - хаотична.  
  

Таким образом в третьем, финальном слое, у меня только чистая бизнес логика:  

- /app/Containers - контейнеры - пафосное слово на замену модулям. Идея та же. В каждом контейнере, в корне, лежит класс с названием контейнера, в котором находятся такие штуки как: краткое название для авто-префикса ресурсов, список провайдеров и миграций (назовем их "штуками из фреймворка", к структуре не относятся).  

Структура каждого контейнера:  
* API/ - все, что касается хттп апи приложения  

 - Controllers/ - контроллеры хттп  

 - Requests/ - классы form request хттп  

 - Tests/ - функциональные тесты этого апи  

 - routes.php - файл раутов
* Broadcasting/ - все, что относится к броадкастингу через сокеты  

 - Events/ - сами классы эвентов  

 - channels.php - файл регистрации каналов броадкастинга
* Configs/ - конфиги этого конкретного контейнера (и НЕ его зависимостей)
* Extra/ - иногда бывает что-то, немного выходящее за рамки контейнера, но еще не входит в Ship. Идет сюда.
* Middlewares/ - хттп миддлвейры
* Database/ - все, что связано с базой данных  

 - Factories/ - файлы пхп, регистрирующие фабрики моделей ларавель  

 - Migrations/ - классы миграций  

 - Seeders/ - сидеры базы  

 - Setup/ - классы-фабрики, обложка над Factories
* Enums/ - энамы
* Exceptions/ - исключения
* JsonResources/ - гсон ресурсы
* Models/ - eloquent модели
* Providers/ - провадйеры
* Services/ - маленькие классы-сервисы, содержащие всю бизнес логику, не привязанные к ХТТП. Каждый сервис выполняет либо одну задачу, либо несколько мелких задач одного типа. Singleton
* Traits/ - трейты

  
  

Все, что я выше указал - либо часть самого языка (как трейты), либо часть фреймворка Laravel. Гуглите.  
  

Есстественно, под разные фреймворки внутренняя структура каждого контейнера может и будет менятся.  
  

PS: БД одна для всего проекта. Зачем вам разные БД, когда есть разные таблицы?)  

PS2: то, что вы себе представили - называется микросервис. Выполняет какой-то небольшой набор задач, имеет отдельную базу и вообще изолирован от всего остального. Но раз вы задаете такие вопросы, вам они точно не нужны. 

 Как вариант использовать Symfony. Уже имеет модульную структуру (модули используют одну БД, но каждый может использовать свои таблицы и быть независимым от остальных) 

 А я бы посоветовал начать с изучения концепта [DDD](https://en.wikipedia.org/wiki/Domain-driven_design) - **Domain Driven Design**. Это позволит уложить в голове структуру по части бизнес логики и как это натянуть на код. А уже организация в конкретном фреймворке - дело второе.