I'm building my own micro MVC framework with only the absolute core functionality. My router will call the controller depending on the request method (GET or POST), and if the called action isn't supported it will default to the index action.
Is my approach correct? Any suggestions for improvement?
abstract class Controller
{
protected $action;
protected $params;
public function __construct($action, $params)
{
$this->action = $action;
$this->params = $params;
}
public abstract function GET();
public abstract function POST();
}
class IndexController extends Controller
{
public function GET()
{
$action = $this->action;
$this->$action();
}
public function POST()
{
$this->GET(); //no POST support
}
private function index()
{
$indexView = new View('index');
$indexView->welcome = 'Welcome!';
$indexView->render();
}
}
1 Answer 1
I would remove both GET()
and POST()
methods from both IndexController
and from Controller
and instead of that I would implement a method getRequest()
in Controller
class.
The getRequest()
method would return Request
object with appropriate API for working with HTTP requests, for example:
isMethod($method)
- usage:isMethod('POST')
get($parameterName)
- usage:get('id')
getLocale()
getBaseUrl()
getHost()
Sample usage would be fore example:
class IndexController extends Controller
function indexAction(){
$request = $this->getRequest();
if ($request->isMethod('POST')){
// Process request
}
// View relevant code
}
}
If you really want to build MVC framework then you should work with views, the good way is for example to create a generic view class which will map controller actions to corresponding view files instead of generating content inside your controller, basically, your controller actions should return an array of parameters, like this:
function indexAction(){
return arrray(
'param' => 'value',
)
}
And after that you should inject the array into view class, which would map the request to proper view file, in your view, which would be called for example index.php
you would just do something like this:
<html>
<body>
<?= escape($param) ?>
</body>
</html>
Although, it is good to use dependency injection pattern. I am not sure if there actually exists any widely used modern MVC framework which does not use it.
It is good to check how MVC is implemented in modern frameworks like Symfony2, Laravel and similar, although Laravel is built upon Symfony2 components.
-
\$\begingroup\$ I actually am using a similar way of returning parameters from the controller action to the View. By using the magic methods that sets variables on the fly. As with
$indexView->welcome = 'Welcome!';
As you might've seen I have a View class that takes care of rendering the templates. \$\endgroup\$Kid Diamond– Kid Diamond2014年05月01日 18:59:37 +00:00Commented May 1, 2014 at 18:59 -
\$\begingroup\$ @KidDiamond I understand, but this shouldn't be done in Controller action. Controller action should just return corresponding array or Object and rendering, mapping view files etc. should be done somewhere else. Such implementation is hard to cover with tests. \$\endgroup\$user41403– user414032014年05月01日 19:05:05 +00:00Commented May 1, 2014 at 19:05
-
\$\begingroup\$ Right now, I'm using one View class to handle every template rendering. So that would mean I have to create a specific View class for every controller or action? And I actually have a RequestHandler that has the exact same methods as you suggested for my Router, so all I would have to do is use this handler and let it work with the Controller too, I think. \$\endgroup\$Kid Diamond– Kid Diamond2014年05月01日 19:08:50 +00:00Commented May 1, 2014 at 19:08
-
\$\begingroup\$ @KidDiamond No, just one generic view class for all Controllers. The view class should accept in its constructor parameters required for rendering corresponding view and the view class should be called automatically at one place. Right now you need to create an instance of view class in each action. \$\endgroup\$user41403– user414032014年05月01日 19:13:38 +00:00Commented May 1, 2014 at 19:13
-
\$\begingroup\$ So the best would be to instantiate only 1 View object per controller, instead of action. Right? \$\endgroup\$Kid Diamond– Kid Diamond2014年05月01日 19:19:51 +00:00Commented May 1, 2014 at 19:19
Explore related questions
See similar questions with these tags.