2010-07-07 15 views
5

Actualmente estoy trabajando en un framework MVC Style para una empresa y por razones de seguridad necesito asegurarme de que el controlador/método que pasa a través de Query String sea válido para el RFC (que no puedo encontrar).Validar nombres de clase/método con regex

tengo que ser capaz de validar/desinfectar los nombres de clases de acuerdo a lo que está permitido por el intérprete PHP

Por ejemplo:

class SomEFunk__YClAssName extends Controller 
{ 

} 

necesito algún tipo de expresiones regulares que validará SomEFunk__YClAssName y desinfectar ¡si es necesario! Este es también el mismo principio que los métodos.

hay un par de cosas a tener en cuenta, como

  • Numerics al inicio
  • sólo subraya permitió
  • Ciertos PHP caracteres especiales que se le permita.

Cualquier información sobre esta o posibles expresiones sería realmente útil.

Aquí es un poco de mi Código router para que pueda ver donde tengo que ponerlo en práctica:

private function prepareQueryString() 
    { 
     if(strlen($this->query_string) == 0) 
     { 
      return; 
     } 
     //Remove [ending|starting|multiple] slashes 
     $this->query_string = preg_replace('/^\/+|\/+$|\/(?=\/)/', '', $this->query_string); 
     foreach(explode('/',$this->query_string) as $Key => $Value) 
     { 
      if($Key == 0) 
      { 
       $Controller = $this->AssignController($Value); 
      } 
      if($Key == 1) 
      { 
       $this->AssignMethod($Value); 
      }else 
      { 
       $this->AssignParam($Value); 
      } 
     } 

     //Build RouterVar stdClass 
    } 

    public function AssignController(String $Controller) 
    { 
     if(!empty($Controller)) 
     { 
      //Sanitize 
     } 
    } 

    public function AssignMethod(String $Method) 
    { 
     if(!empty($Method)) 
     { 
      //Sanitize 
     } 
    } 

    public function AssignParam(String $Param) 
    { 
     $this->params[] = $Param; 
    } 

podrás ver el comentario "Higiénico" donde se necesita el cheque.

Respuesta

17

Creo que la expresión regular que busca es:

<?php 
preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $input); 
?> 

De acuerdo con: http://php.net/manual/en/language.oop5.basic.php

+0

Gracias por el ejemplo de código y el enlace de documentación. Lo hubiera marcado como la respuesta. – Xunnamius

+2

** Atención **: creo que hay un defecto en su 'preg_match', ya que no se da ningún delimitador de inicio/final. Su código con '$ input =" ¡Definitivamente no es un nombre de clase válido! '' Devolverá 1. Si lo cambia a 'preg_match ('/^[a-zA-Z_ \ x7f- \ xff] [a-zA-Z0- 9_ \ x7f- \ xff] * $/', $ input); 'devuelve 0. –

+0

Buena llamada en el delimitador de inicio/finalización. – nate

6

Le conviene usar una expresión regular muy general y luego probar que la clase existe con una simple llamada al class_exists().

Esto coincidirá con cualquier nombre de la clase PHP válida, incluyendo los realmente extrañas como ___ o _3, ambos de los cuales son los nombres de clase válidos:

/^[a-z_]\w+$/i 

personalmente estoy más restrictivas que las convenciones de nombres de PHP para las clases. Exijo que mis controladores se escriban en mayúscula y se fijen con _controller para que no se invoquen extrañas clases que no sean de controlador a través de URLs extrañas. Me gustaría usar algo como esto:

class Products_controller extends Controller { } 

// elsewhere, after parsing the controller name from the URI: 

if (preg_match('/^[A-Z]\w+_controller$/', $controller_name) 
&& class_exists($controller_name)) { 
    $controller = new $controller_name(); 
} 

Como acotación al margen, pasando el nombre del controlador a través de los rendimientos de cadena de consulta muy feos y los motores de búsqueda URL hostiles. Considerar la construcción el nombre del controlador y el método en la URL:

/products/index # controller=products, action=index 
/users/show/3 # controller=users, action=show, user id=3 
+0

me ocurre hacer esto '^(? = _ * [Az] +) [A-z0-9 _] + $ 'pero todavía hay caracteres que deberían permitirse, por ejemplo,' clase € 1 {} 'y' clase €€ _ {} ' – RobertPitt

+0

If realmente quieres invocar cualquier clase nombrada arbitrariamente, entonces, literalmente, todo lo que te importa es si la clase existe. Omita la expresión regular por completo, no agrega nada de seguridad, y simplemente marque 'class_exists()'. – meagar

Cuestiones relacionadas