Кирилл Несмеянов, многопоточность - это про потоки, асинхронность - это работа функций, не совпадающих во времени. Асинхронные функции всегда выполняются в одном потоке.
Максим Федоров, там, где вы это прочитали, говорят забыть про все суффиксы, а не только Service. И при чем здесь вообще Repository? У него типичная AR модель.
Антон Р., у вас просто по цепочке вызов. и, кстати, неясно, что делать, если вызвать setMess, т.к. он не возвращает $this. Надо ли говорить, что у вас еще и закон Деметры нарушается. В общем, как мне кажется, это совсем не то, о чем спрашивал ТС.
Антон Р., это примерно то же самое, что вы написали, только ваш роутер занимается созданием контроллера и вызовом экшена. я считаю, это не его обязанность. роутер должен лишь иметь коллекцию роутов, разбирать запрос и возвращать контроллер. к тому же у вас контроллеры голые, методы голые, без параметров, в реальной жизни контроллерам нужны сервисы по работе с базой, нужен реквест, доступ к кукам, сессиям и так далее. передать это все руками тоже нельзя, потому что у разработчика должна быть возможность у одного контроллера вообще не иметь параметры, у другого иметь их штук 5. в общем, тут этим занимается контейнер, у которого есть различные провайдеры, умеющие автовайрить (загружать) аргументы по их типу. ТС может про рефлексию почитать. Ну а уже после заполненного контроллера вызывать его может ядро проекта (в симфони, к примеру, это HttpKernel).
ixon, все начинается с index.php. В нем создается реквест (не используйте глобальные переменные в ядре своего проекта, просто передавайте реквест туда, где он вам нужен), создается экземпляр контейнера, в котором хранится вся низкоуровневая информация для ваших сервисов (данные базы, пути к папкам кэша и так далее), о которых контейнер знать не может. Дальше из реквеста достается path (урл, по которому юзер сделал запрос), мэтчите его на контроллер (тут в работу вступает роутер, которому вы передаете коллекцию роутов (controller -> route) и текущий path, регулярками или как-либо еще парсите path, достаете маршрут, возвращаете данные о вызываемом контроллере), создаете экземпляр вашего контроллера (это может быть класс и метод, callable, да даже простая ф-ция), пропускаете его конструктор и вызываемый экшен через контейнер, кладете все нужные аргументы, возвращаете респонс (тут и заголовки, и все остальное делаете).
Антон Р., извините меня, это тостер, а не гугл. Я мог бы сюда кинуть ссылки по запросу из гугла, но вы их сами без труда найдёте. Если коротко, uuid можно генерировать самому и не надеяться на lastInsertId. Это удобно, когда нужно в момент сохранения сразу связать запись с другой таблицей и/или послать событие в очередь, которое кто-то потом обработает. Это не костыль, это стандарт, такой же, как автоинкремент, но если начинать, то либо с автоинкремента, либо с uuid
DevMan, а почему не конструктор? То есть вы к вопросу о конструкторе опустили типизацию, которая важна, чтобы что? Чтобы ТС сам догадался, что нужно использовать сеттеры?
А почему не написали, что через конструктор можно типы контролировать? У свойств пока ещё нет типов, а у аргументов есть. Поэтому свойства делают приватными, а инициализацию помещают в конструктор.