Отдельный файл routes.php и вызов в нем методов контроллера

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Закрыто
PC_Principal
Сообщения: 8
Зарегистрирован: 2017.04.26, 11:51

Отдельный файл routes.php и вызов в нем методов контроллера

Сообщение PC_Principal »

Добрый день, уважаемые форумчане! Недавно озадачился выносом всех путей маршрутизации из config/web.php в config/routes.php и вызовом статических методов в маршрутах вместо строк в Yii2 basic.

Имеются следующие файлы:

config/web.php - секция urlManager

Код: Выделить всё

urlManager' => [
   'enablePrettyUrl' => true,
   'showScriptName' => false,
   'enableStrictParsing' => true,
   'rules' => require DIR . '/routes.php'
],
config/routes.php

Код: Выделить всё

use app\controllers\SiteController;

return [
   "" => SiteController::routeId(SiteController::ACTION_INDEX),
];
controllers/AdvancedController

Код: Выделить всё

<?php

namespace app\controllers;

use Yii;

class AdvancedController extends \yii\web\Controller
{
	use ControllerRoutesTrait;
}
controllers/ControllerRoutesTrait

Код: Выделить всё

<?php

namespace app\controllers;

use yii\helpers\Inflector;
use yii\helpers\StringHelper;

trait ControllerRoutesTrait
{
	/**
	 * Получение маршрута на указанное действие с указанными параметрами.
	 *
	 * @param string $action Название действия
	 * @param array  $params Дополнительные параметры
	 *
	 * @return array
	 */
	public static function getUrlRoute(string $action, array $params = []): array
	{
		$path = static::routeId($action);

		return array_merge(['/' . $path], $params);
	}

	/**
	 * Getting route id, can be passed to routes
	 */
	public static function routeId(string $action): string
	{
		preg_match('#\\\\modules\\\\(?P<module>.+?)\\\\#', static::class, $matches);
		$module = ($matches['module'] ?? null);

		$controller = StringHelper::basename(static::class);
		$controller = preg_replace('/Controller$/', '', $controller);
		$controller = Inflector::camel2id($controller);
		$path       = implode('/', array_filter([$module, $controller, $action]));

		return $path;
	}
}
controllers/SiteController

Код: Выделить всё

<?php

namespace app\controllers;

use app\controllers\AdvancedController;

class SiteController extends AdvancedController
{
	const ACTION_INDEX = 'index';

	public function actionIndex()
	{
	    return $this->render('index.php')
        }
}
Проблема заключается в том, что при такой реализации при попытке зайти на сайт Nginx выбрасывает 500 ошибку со следующим текстом:
PHP Fatal error: Uncaught Error: Class 'app\controllers\SiteController' not found in config\router.php on line 4
Долго мучался так и не смог разобраться, в чем проблема - при этом отдельное тестирование такой конструкции print_r(SiteController::routeId(SiteController::ACTION_INDEX)) в другом контроллере показывает что возвращается строка 'site/index'.

Очень хочу разобраться с этой проблемой, т.к. подход такой к построению маршрутов понравился + точно помню что видел проект, где этот подход работал без ошибок.

Буду очень рад любым мыслям на этот счет!
PC_Principal
Сообщения: 8
Зарегистрирован: 2017.04.26, 11:51

Re: Отдельный файл routes.php и вызов в нем методов контроллера

Сообщение PC_Principal »

Разобрался с проблемой, это связано с отсутствием алиаса @app на стадии инициализации приложения, решается следующим образом:

Создаем следующий файл: config/bootstrap.php со следующим содержимым:

Код: Выделить всё

<?php
Yii::setAlias('@app', dirname(__DIR__));
И в index.php приводим все к подобному виду:

Код: Выделить всё

// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
require __DIR__ . '/../config/bootstrap.php';

$config = require __DIR__ . '/../config/web.php';

(new yii\web\Application($config))->run();
В таком варианте можно обращаться к классам контроллера на стадии инициализации приложения.
Закрыто