Никаким. Его не должно быть. Вообще. Только сразу камнями не закидываете.
Разъясню.
1. Контроллеры в большинстве случаев не имеют состояний, а объект без состояния лишь дополнительное пространство имен для функций.
2. Реализации
В небольших приложениях в контроллеры наваливают бизнес логику, чтобы не тратить время на построение архитектуры. Оно себя оправдывает. Да мы лишаем себя возможности модульных тестов, но функциональные остаются рабочими. И это является противоречием назначению контроллера.
class RobotsControlller
{
public function inactiveRobots()
{
$robots = Robots::find()->where(['active' => false])->all();
foreach ($robots as $robot) {
$robot->active = true;
$robot->save();
}
return $this->render('robots', [
'robots' => $robots
]);
}
}
В проектах средней величины уже пытаются выносить бизнес логику в сервисы. Сервисный слой это и есть модель из множества классов. В контроллере вызывается один-два из этих сервисов и данные передаются в представление. И все бы хорошо, связующее звено для сервисов..., но это грамотно завуалированная бизнес логика, которую отчетливо видно лишь в крупных проектах.
class RobotsControlller
{
public function inactiveRobots()
{
$container = $this->getContainer();
$robotsService = $container->getRobotsService();
$robots = $robotsService->getInactiveRobots();
$stationService = $container->getStationService();
$stationService->acivateRobots($robots);
return $this->render('robots', [
'robots' => $robots
]);
}
}
В гораздо больших проектах количество различных сервисов возрастает в разы, контроллер превращается в один большой экшен, который сам является сервисом, чтобы тратить меньше времени на поиск необходимого куска кода.
3. Как же все-таки правильно.
Отказываться от контроллеров и пилить свой велосипед на текущий момент слишком затратно по времени на всех проектах меньше больших. Мой ответ будет прост - использовать здравый смысл, сохранять семантику и не забывать об удобстве. Называете вещи своими именами и придерживайтесь однородности. Если строите api на типах resource (get | delete | put | post) то придерживайтесь этого стиля, не мешайте со стандартными экшенами. Разобравшись в одном будет проще понять работу всего остального.
4. Примеры из жизни
Рассмотрите любые примеры из реальной жизни. Например, процедуру покупки продуктов в супермаркете или покупки билета в метро. Контроллером является кассир, который принимает входящие данные (товары и деньги) и отдает представление (чек). Но со временем роль кассира начинает выполнять автомат, покупатель сам пробивает товары или покупает билет на проезд. Контроллер поменялся. Через еще некоторое время билет покупать уже не требуется, есть просто телефон с NFC, а в супермаркете просто получаем товары по заранее отправленному с этого же телефона заказу.
В каждом MVC много других маленьких MVC, скажете вы, ища оправдания необходимости контроллера.
p.s. можно начинать кидать камни)