He puesto este tema como PHP porque aun no se sabe si es un tema unicamente de .htaccess o si tambien habrá que tocar código de php.
tu solución fue lo primero que intente en su momento, pero entonces sucede lo siguiente:
las url dejan de ser amigables
http://localhost/php-mvc/language/?url=language
en vez de
http://localhost/php-mvc/language/
y esto solo sucede cuando hay conflicto con un directorio
Mas info, el fichero index.php lanza el Boostrap
fichero index.php
Código PHP:
require_once ROOT.'core'.DS.'init.php';//inizializo la app
$registry= coremvcRegistry::getInstance();//instancio el registry
$registry->_request=new coremvcRequest();//recogo la petición del cliente mediante Request.php y almaceno la instancia en registry
coremvcBootstrap::run($registry->_request);//lanzo el Bootstrap pasandole el Request, que llamara a un método de un controlador
fichero Request.php
Código PHP:
class Request{
private $_controller;
private $_method;
private $_args;
private $_module;
public function __construct(){
if(isset($_GET['url'])){
$url=filter_input(INPUT_GET,'url',FILTER_SANITIZE_URL);//coge el parametro url via get y lo sanitiza(filtra)
$url=explode('/',$url);//parte la url por cada slash, crea un array
$url=array_filter($url);//filtra los valores null,false,-1,...
/*asignamos cada parte de la url con array_shift(recupera y quita el primer elemento)
transformaremos a lowercase las partes
hay 2 posibilidades:
1.modulo/controlador/metodo/argumentos
2.controlador/metodo/argumentos
*/
//el strlower hace que no se discrimine minusculas o mayusculas accediendo al modulo, se repite lo mismo en el controlador y en el método
$module=strtolower(array_shift($url));
global $modules;//accedemos a la variable global $modules(array) de init.php que contiene los modulos
//si el array contiene algo y el primer paremtro de la url coincide con un modulo
if(count($modules) && in_array($module, $modules)){
$this->_module=$module;
$this->_controller=strtolower(array_shift($url));
}else{
$this->_module=false;
$this->_controller=$module;
}
$this->_method=strtolower(array_shift($url));
if($url){//si queda algo en el array
$url=array_map('strtolower',$url);//convertimos a lower todos los elementos del array
$this->_args=$url;//le damos el resto de la url, en los argumento si se dicrimina el minus o mayus
}
}
/*comprueba que se an rellenado las propiedades, si no las inizializa de serie*/
if(!$this->_controller) $this->_controller = DEFAULT_CONTROLLER;
if(!$this->_method) $this->_method = 'index';
if(!isset($this->_args)) $this->_args=array();
}
public function getModule(){
return $this->_module;
}
public function getController(){
return $this->_controller;
}
public function getMethod(){
return $this->_method;
}
public function getArgs(){
return $this->_args;
}
}
fichero Bootstrap.php
Código PHP:
class Bootstrap{
public static function run(Request $request){
coreutilsConsoleLog::consolePrint('log', 'bootstrap');
/*obtenemos las partes del request*/
$module=$request->getModule();
$controller=$request->getController().'Controller';//concatenamos controller
$method=$request->getMethod();
$args=$request->getArgs();
//creamos la ruta al controlador
if($module)$ruteController=MODULES_PATH.$module.DS.'controllers'.DS.$controller.'.php';
else $ruteController=CONTROLLERS_PATH.$controller.'.php';
if(is_readable($ruteController)){//si ese controlador existe
require_once $ruteController;//incluimos el controlador ejemplo: indexController
$controller=new $controller;//instanciamos la clase, ahora $controller es un objeto
//comprobamos que el método se puede llamar en esa instancia del controlador
if(!is_callable(array($controller,$method))){
/*si no es callable, es decir no exite el método se asignara el de por defecto index que siempre existirá
debido a que es un método abstracto de la clase padre Controller*/
$method='index';
}
//comprobamos que hayan argumentos
if(isset($args) && !empty($args)){
//llamamos al método pasandole los argumentos
call_user_func_array(array($controller, $method), $args);
}else{
//llamamos al método sin pasarle argumentos
call_user_func(array($controller,$method));
}
}else{
throw new coreexceptionsPageNotFoundException();
}
}
}