Foros del Web » Programando para Internet » PHP »

mvc conflicto entre controlador y directorio

Estas en el tema de mvc conflicto entre controlador y directorio en el foro de PHP en Foros del Web. Hola a todos Bueno el tema es que estoy creando con php un sistema mvc, y para ello utilizo un .htaccess que redirige las peticiones ...
  #1 (permalink)  
Antiguo 11/09/2014, 04:37
 
Fecha de Ingreso: abril-2013
Mensajes: 22
Antigüedad: 11 años
Puntos: 0
mvc conflicto entre controlador y directorio

Hola a todos

Bueno el tema es que estoy creando con php un sistema mvc, y para ello utilizo un
.htaccess que redirige las peticiones a un fichero index.php?url=$variable

Código PHP:
<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond 
%{REQUEST_FILENAME} !-d
RewriteCond 
%{REQUEST_FILENAME} !-f
RewriteCond 
%{REQUEST_FILENAME} !-l

RewriteRule 
^(.+)$ index.php?url=$[QSA,L]
</
IfModule
la historia es que cuando la variable que le paso coincide con el nombre de un directorio
accede al directorio en vez lanzar en index.php (para redirigir al controlador)

e mirado bastande info sobre .htacces pero no e conseguido nada, haber si alguien sabe por donde hay que tirar para solucionarlo

saludos y gracias de antemano
  #2 (permalink)  
Antiguo 11/09/2014, 06:39
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: mvc conflicto entre controlador y directorio

El tema de configuración de Apache (.htaccess) no corresponde a programación en PHP, te equivocaste de foro.

No obstante debes saber que la bandera !-d verifica "que no sea un directorio" y bueno, eso obviamente evita que tu regla se aplique cuando colocas el nombre del directorio en la URL.

Consulta una referencia de mod_rewrite.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 11/09/2014, 07:12
 
Fecha de Ingreso: abril-2013
Mensajes: 22
Antigüedad: 11 años
Puntos: 0
Respuesta: mvc conflicto entre controlador y directorio

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
    
$registrycoremvcRegistry::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();
        }
    }
    


Última edición por jokinini; 11/09/2014 a las 07:13 Razón: fallo
  #4 (permalink)  
Antiguo 11/09/2014, 07:17
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: mvc conflicto entre controlador y directorio

Desde luego es un tema únicamente de Apache, porque Apache es quien aplica mod_rewrite, tu script sólo recibe la petición re escrita.

Jamás ha sido un tema de PHP porque PHP no es el servidor, PHP no aplica mod_rewrite.

Cuando dices "accede al directorio" estás describiendo un comportamiento de Apache, ¿o tu programaste en PHP algo así?

Has una prueba simple, el mismo .htaccess y scripts sencillos de PHP, sin bootstraps ni routers.

¿Sucede lo mismo?

PDTA: por eso, una buena técnica para evitar esto es ubicar los directorios de tu aplicación fuera del DOCUMENT_ROOT, así jamás serán alcanzados por el servidor web.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #5 (permalink)  
Antiguo 11/09/2014, 07:32
 
Fecha de Ingreso: abril-2013
Mensajes: 22
Antigüedad: 11 años
Puntos: 0
Respuesta: mvc conflicto entre controlador y directorio

index.php
Código PHP:
<?php
if(isset($_GET['url'])){

    
$url=$_GET['url'];    
    echo 
$url;
}else{
    echo 
'no hay get url';
}


ejemplo: localhost/Test/language

1.con !-d

Código PHP:
<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond 
%{REQUEST_FILENAME} !-d
RewriteCond 
%{REQUEST_FILENAME} !-f
RewriteCond 
%{REQUEST_FILENAME} !-l

RewriteRule 
^(.+)$ index.php?url=$[QSA,L]
</
IfModule
como el directorio language existe me muestra su arbol en vez de imprimir language

2.sin !-d

Código PHP:
<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond 
%{REQUEST_FILENAME} !-f
RewriteCond 
%{REQUEST_FILENAME} !-l

RewriteRule 
^(.+)$ index.php?url=$[QSA,L]
</
IfModule
imprime language, pero la url queda de la siguente forma
http://localhost/Test/language/?url=language
y eso no quiero que suceda
  #6 (permalink)  
Antiguo 11/09/2014, 07:35
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: mvc conflicto entre controlador y directorio

Cita:
como el directorio language existe me muestra su arbol en vez de imprimir language
¿Ves?

Entonces sí es un tema de Apache y no de PHP claramente.

En teoría sólo debes agregar más condiciones a tu .htaccess para que funcione.

Por favor consulta una referencia de mod_rewrite ya que no es un tema de programación PHP.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.

Etiquetas: .htaccess
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 02:55.