I was working with a MVC architecture in my php webapp. My architecture it's pretty simple, if I send a request to an url in this way localhost/Dispatcher.php?class=SampleController&method=sampleMethod
this will instantiate the controller SampleController
and invoke the method sampleMethod
of this controller. BTW I can't use the .htaccess file. Now I want to get rid of the Dispatcher.php
, so I thought that I could achieve that if I change the sintax of the url to something like this localhost/SampleController.php?method=sampleMethod
. To do this I must use $_SERVER['SCRIPT_NAME']
to get the controller class name. All my controllers extends from Controller
. I thought that I could instantiate the controller there, in the Controller.php
. So, my Controller.php
looks like this.
<?php
//Enable errors
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
//Include the controller
$include = explode("/",$_SERVER['SCRIPT_NAME'])[2]; //This return MainController.php
include_once $include;
//Get the method (Like this is an example I don't care the validations)
$method = $_GET['method'];
$class = explode(".",$include)[0]; //Get rid of the *.php extention
$controller = new $class();
$controller->$method(); // I get Class 'MainController' not found
include_once 'View.php';
class Controller {
public $view;
public function __construct() {
$this->view = new View();
}
}
?>
And this is my MainController.php
<?php
include_once 'Controller.php';
include_once 'MainModel.php';
class MainController extends Controller {
public $model;
public function __construct() {
parent::__construct();
$this->model = new MainModel();
}
public function index(){
$this->view->render('mainView','headerMain','footerMain');
}
}
?>
Here I'm trying to hit this url MainController.php?method=index
All the names are ok, the paths are also ok. BTW if I hardcode the paths I get the same error, can be this a includes error? If I can't achieve this in the Controller.php
there's some place where I can handle the controller instantiation without add another .php file? (I don't want get back to use the Dispatcher.php
)
UPDATE
If I change the Controller.php
in this way, works, but I get an Fatal error: Cannot redeclare class maincontroller in MainController.php on line 9
<?php
include_once 'View.php';
//Enable errors
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
//Include the controller
$include = explode("/",$_SERVER['SCRIPT_NAME'])[2]; //This return MainController.php
//Get the method (Like this is an example I don't care the validations)
$method = $_GET['method'];
$class = explode(".",$include)[0];
require($include);
$controller = new $class();
$controller->$method();
class Controller {
public $view;
public function __construct() {
$this->view = new View();
}
}
?>
WORKAROUND
I achieved what I want in this way:
MainController.php
<?php
//Enable errors
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
include_once 'Controller.php';
include_once 'MainModel.php';
class MainController extends Controller {
public $model;
public function __construct() {
parent::__construct();
$this->model = new MainModel();
}
public function index(){
$this->view->render('mainView','headerMain','footerMain');
}
}
require_once("Core.php");
?>
Controller.php
<?php
include_once 'View.php';
class Controller {
public $view;
public function __construct() {
$this->view = new View();
}
}
?>
Core.php
<?php
//Enable errors
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
//Include the controller
$include = explode("/",$_SERVER['SCRIPT_NAME'])[2]; //This return MainController.php
//Get the method (Like this is an example I don't care the validations)
$method = $_GET['method'];
$class = explode(".",$include)[0];
$controller = new $class();
$controller->$method();
?>
But this solution still doesn't satisfice me, this isn't the object oriented solution that I want. Isn't some way of do this in the Controller.php
?