Как сделать Router для PHP фреймфорка?

Добрый день всем!

Пишется небольшой фреймворк.
Упрощенная структура файлов такая:
-Apps
--Config.php
--Router.php
--Template.php
--DB.php
--Mail.php
-HTML
--css
--images
--js
--main.tpl
-Modules
--Main
---Controller.php
---Model.php
--Feedback
---Controller.php
---Model.php
.....
.htaccess
index.php

основное отличие от тех фреймфорков что нашел (перерыл достаточно):
есть что то типа "модуль" в который отличается самодостаточностью.
Имеется папка Modules в ней хранятся "модули"
каждый модуль это папка в которой имеются файлы Controller.php и Model.php (так же папка view c шаблонами)

Прошу помощи разобраться с роутером - классом который в соответствии с запросом вызовет определенный контроллер, код сейчас такой:

<?php
namespace Apps;

class Router {
	public $modul	= 'Main';
	public $action	= 'view';
	public $id		= null;
	public $param	= array();
	public $params	= false;

	public function __construct()
	{
		$request = explode("/", Request::get('route'));
		
		if($request) foreach($request as $key=>$req)
		{
			if(!$req) continue;
			if($key==0) $this->modul 	= $req;
			if($key==1) $this->action 	= $req;
			if($key==2) $this->id 		= $req;
			if($key>2) $this->param[]	= $req;
		}

		require_once ROOT.DIR_SEP.'Modules'.DIR_SEP.$this->modul.DIR_SEP.'Controller.php';

		new Controller($this->action, $this->id);
	}
}


необходимо что бы он красиво запускал Controller (Controller.php) из модуля (папки) $this->modul, желательно через стандартную функцию автолоад и/или пространство имен \Modules\$this->modul\Controller
без этого инклуда ROOT.DIR_SEP.'Modules'.DIR_SEP.$this->modul.DIR_SEP.'Controller.php';
  • Вопрос задан
  • 3423 просмотра
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
По поводу инклудов - читаем про PSR-0/PSR-4 автозагрузку.

$className = sprintf('\MyCoolFramework\Module\%s\Controller', $this->modul);
// подключать не нужно, для этого нужен автозагрузчик 
// который из неймспеса и названия класса сгенерит вам путь к файлу и подключит его
// некрасивый способ
$controller = new $className();
// красивый способ, но медленный, зато с плюшками
$class = new ReflectionClass($className);
$controller = $class->newInstance();


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

Так же хочу вам посоветовать перейти на раутинг на основе регулярок и массива правил. Так как один контроллер на модуль это грустно. Ну и да, надеюсь вы это для учебных целей делаете. В любом случае я бы на вашем месте начал с реализации контейнера зависимостей и управления конфигами.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
miraage
@miraage
Старый прогер
Если Вам нужен именно роутер - самое лучшее решение из существующих.

https://github.com/nikic/FastRoute
Ответ написан
Комментировать
pavel_salauyou
@pavel_salauyou
Symfony2 & Angular разработчик
основное отличие от тех фреймфорков что нашел (перерыл достаточно):
есть что то типа "модуль" в который отличается самодостаточностью - это есть в любом современном фреймворке
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы