route name igniter code php regex codeigniter routes

php - name - routes code igniter



Codeigniter Routes regex: uso de guiones en los nombres de controlador/método (9)

Estoy buscando una ruta de una línea para enrutar el nombre del método y el controlador punteado al controlador subrayado real y los nombres de los métodos.

Por ejemplo, la URL

/controller-name/method-name-which-is-long/

Dirigiría a

/controller_name/method_name_which_is_long/

ver: http://codeigniter.com/forums/viewreply/696690/ que me dio la idea de preguntar :)


Anular la clase de Enrutador es un buen enfoque, también hay una forma de reemplazarlo con _ registrando un enganche "pre-sistema".

Primero crea el gancho agregando estas líneas a tu archivo ''config / hooks.php'':

$hook[''pre_system''] = array( ''class'' => '''', ''function'' => ''prettyurls'', ''filename'' => ''myhooks.php'', ''filepath'' => ''hooks'', ''params'' => array() );

Ahora crea un archivo ''myhooks.php'' en la carpeta ''application / hooks'' y agrega esta función (no olvides abrir una etiqueta PHP si este es el primer enlace):

<?php function prettyurls() { if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), ''/'') != '''') { $newkey = str_replace(''-'',''_'',key($_GET)); $_GET[$newkey] = $_GET[key($_GET)]; unset($_GET[key($_GET)]); } if (isset($_SERVER[''PATH_INFO''])) $_SERVER[''PATH_INFO''] = str_replace(''-'',''_'',$_SERVER[''PATH_INFO'']); if (isset($_SERVER[''QUERY_STRING''])) $_SERVER[''QUERY_STRING''] = str_replace(''-'',''_'',$_SERVER[''QUERY_STRING'']); if (isset($_SERVER[''ORIG_PATH_INFO''])) $_SERVER[''ORIG_PATH_INFO''] = str_replace(''-'',''_'',$_SERVER[''ORIG_PATH_INFO'']); if (isset($_SERVER[''REQUEST_URI''])) $_SERVER[''REQUEST_URI''] = str_replace(''-'',''_'',$_SERVER[''REQUEST_URI'']); }

Probablemente necesites editar tu archivo ''config / config.php'' para habilitar hooks (alrededor de la línea 91 para mí):

$config[''enable_hooks''] = TRUE;

Esta respuesta está extraída de codeigniter.com/forums/viewthread/124396/#644012


Creo que lo que está buscando es un enlace pre-sistema o un control previo que tomará el URI solicitado y lo actualizará.


En realidad esto es nativo ahora en Codeigniter 3 Solo haz esto en el archivo de rutas

$route[''translate_uri_dashes''] = TRUE;

Y lo hará por controladores y métodos de forma automática.
Por favor, vote esta respuesta, ya que es la más reciente


Ese es exactamente mi requisito también y estaba usando rutas como

$route[''logued/presse-access''] = "logued/presse_access";

En mi proyecto anterior necesitaba crear 300-400 reglas de enrutamiento, la mayoría de ellas se deben guiar para subrayar la conversión.

Para mi próximo proyecto, ansiosamente quiero evitarlo. He hecho un truco rápido y lo he probado, aunque no lo he usado en ningún servidor en vivo, está funcionando para mí. Haz lo siguiente..

Asegúrese de que el subclass_prefix sea el siguiente en su sistema / application / config / config.php

$config[''subclass_prefix''] = ''MY_'';

A continuación, cargue un archivo llamado MY_Router.php en el directorio system / application / libraries.

<?php class MY_Router extends CI_Router { function set_class($class) { //$this->class = $class; $this->class = str_replace(''-'', ''_'', $class); //echo ''class:''.$this->class; } function set_method($method) { // $this->method = $method; $this->method = str_replace(''-'', ''_'', $method); } function _validate_request($segments) { // Does the requested controller exist in the root folder? if (file_exists(APPPATH.''controllers/''.str_replace(''-'', ''_'', $segments[0]).EXT)) { return $segments; } // Is the controller in a sub-folder? if (is_dir(APPPATH.''controllers/''.$segments[0])) { // Set the directory and remove it from the segment array $this->set_directory($segments[0]); $segments = array_slice($segments, 1); if (count($segments) > 0) { // Does the requested controller exist in the sub-folder? if ( ! file_exists(APPPATH.''controllers/''.$this->fetch_directory().str_replace(''-'', ''_'', $segments[0]).EXT)) { show_404($this->fetch_directory().$segments[0]); } } else { $this->set_class($this->default_controller); $this->set_method(''index''); // Does the default controller exist in the sub-folder? if ( ! file_exists(APPPATH.''controllers/''.$this->fetch_directory().$this->default_controller.EXT)) { $this->directory = ''''; return array(); } } return $segments; } // Can''t find the requested controller... show_404($segments[0]); } }

Ahora puede usar libremente url como http://example.com/logued/presse-access y llamará al controlador y a la función adecuados convirtiendo automáticamente el guión en guión bajo.

Editar: Aquí está nuestra solución Codeigniter 2 que anula las nuevas funciones CI_Router:

<?php class MY_Router extends CI_Router { function set_class($class) { $this->class = str_replace(''-'', ''_'', $class); } function set_method($method) { $this->method = str_replace(''-'', ''_'', $method); } function set_directory($dir) { $this->directory = $dir.''/''; } function _validate_request($segments) { if (count($segments) == 0) { return $segments; } // Does the requested controller exist in the root folder? if (file_exists(APPPATH.''controllers/''.str_replace(''-'', ''_'', $segments[0]).''.php'')) { return $segments; } // Is the controller in a sub-folder? if (is_dir(APPPATH.''controllers/''.$segments[0])) { // Set the directory and remove it from the segment array $this->set_directory($segments[0]); $segments = array_slice($segments, 1); while(count($segments) > 0 && is_dir(APPPATH.''controllers/''.$this->directory.$segments[0])) { // Set the directory and remove it from the segment array $this->set_directory($this->directory . $segments[0]); $segments = array_slice($segments, 1); } if (count($segments) > 0) { // Does the requested controller exist in the sub-folder? if ( ! file_exists(APPPATH.''controllers/''.$this->fetch_directory().str_replace(''-'', ''_'', $segments[0]).''.php'')) { if ( ! empty($this->routes[''404_override''])) { $x = explode(''/'', $this->routes[''404_override'']); $this->set_directory(''''); $this->set_class($x[0]); $this->set_method(isset($x[1]) ? $x[1] : ''index''); return $x; } else { show_404($this->fetch_directory().$segments[0]); } } } else { // Is the method being specified in the route? if (strpos($this->default_controller, ''/'') !== FALSE) { $x = explode(''/'', $this->default_controller); $this->set_class($x[0]); $this->set_method($x[1]); } else { $this->set_class($this->default_controller); $this->set_method(''index''); } // Does the default controller exist in the sub-folder? if ( ! file_exists(APPPATH.''controllers/''.$this->fetch_directory().$this->default_controller.''.php'')) { $this->directory = ''''; return array(); } } return $segments; } // If we''ve gotten this far it means that the URI does not correlate to a valid // controller class. We will now see if there is an override if ( ! empty($this->routes[''404_override''])) { $x = explode(''/'', $this->routes[''404_override'']); $this->set_class($x[0]); $this->set_method(isset($x[1]) ? $x[1] : ''index''); return $x; } // Nothing else to do at this point but show a 404 show_404($segments[0]); } }

Ahora uno tiene que colocar este archivo como application / core / MY_Router.php y asegurarse de que tiene subclass_prefix definido como $config[''subclass_prefix''] = ''MY_''; en application / config / config.php

Se han agregado pocas líneas adicionales de código en el método _validate_request() :

while(count($segments) > 0 && is_dir(APPPATH.''controllers/''.$this->directory.$segments[0])) { // Set the directory and remove it from the segment array $this->set_directory($this->directory . $segments[0]); $segments = array_slice($segments, 1); }

Se usa para que se pueda usar el subdirectorio de niveles múltiples dentro del directorio de controladores, mientras que normalmente podemos usar el subdirectorio de un solo nivel dentro de la carpeta de controladores y podemos llamarlo en url. Uno puede eliminar este código si no es necesario, pero no tiene ningún daño en el flujo normal.


Esta es una vieja pregunta, pero me gustaría publicar que e-mike tenía una gran solución para este problema, y ​​mucho más simple.

<?php public function _set_request($segments){ // Fix only the first 2 segments for($i = 0; $i < 2; ++$i){ if(isset($segments[$i])){ $segments[$i] = str_replace(''-'', ''_'', $segments[$i]); } } // Run the original _set_request method now, giving it our newly replaced segments parent::_set_request($segments); } ?>

Espero que esto ayude a cualquier otra persona con este problema.


No estoy seguro si podrías hacer eso con una ruta ...

Sin embargo, en algún lugar de las bibliotecas centrales de Codeigniter (posiblemente Router o URI) se convertirá el uris subrayado en un nombre de clase de camelcase.

Eché un vistazo rápido y no pude encontrarlo, pero si lo hace, simplemente copie esa biblioteca en su carpeta de aplicaciones / bibliotecas y modifíquela allí.


Puede usar este método _remap () para manejar dicho comportamiento. Coloque este método en sus controladores o cree un controlador central y colóquelo.

public function _remap($method, $params = array()){ if(method_exists($this, $method)){ return call_user_func_array(array($this, $method), $params); }else{ $method = str_replace("-", "_", $method); if(method_exists($this, $method)){ return call_user_func_array(array($this, $method), $params); } } show_404(); }


Volviendo a esta pregunta después de actualizar a CodeIgniter 2. Aquí hay una solución que es más sólida que la respuesta aceptada porque sobrevivirá a las actualizaciones principales de CodeIgniter.

<?php class MY_Router extends CI_Router { public function set_class($class) { parent::set_class($this->_repl($class)); } public function set_method($method) { parent::set_method($this->_repl($method)); } public function _validate_request($segments) { if (isset($segments[0])) $segments[0] = $this->_repl($segments[0]); if (isset($segments[1])) $segments[1] = $this->_repl($segments[1]); return parent::_validate_request($segments); } private function _repl($s) { return str_replace(''-'', ''_'', $s); } }

Debe guardarse como application/core/MY_Router.php . Ahora, puede tener nombres de Controlador y Método con guiones bajos en ellos, como Abc_Def (en el archivo abc_def.php ) y hacer referencia a ellos con la URL /abc-def .


<?php class MY_Router extends CI_Router { function _set_request($segments = array()) { parent::_set_request(str_replace(''-'', ''_'', $segments)); } } ?>

Coloque este archivo MY_Router.php en / application / libraries (CI1) o / application / core (CI2) Recuerde que esto afectará a todos los segmentos, no solo al módulo, controlador y método.

Alternativa a esta extensión es agregar cada segmento a router.php $ route [''this-is-a-module-or-controler''] = ''this_is_a_module_or_controller'';

Como puede ver, el método extender sería más fácil de usar. Puede optar por hacer que la función también maneje solo los primeros dos o tres segmentos para que los otros segmentos no se vean afectados por el reemplazo _.