2010-07-07 89 views
5

我目前正在为一家公司开发MVC样式框架,并且出于安全原因,我需要确保通过查询字符串传递的控制器/方法是RFC的有效字符我找不到)。使用正则表达式验证类/方法名称

我需要能够验证/根据什么由PHP解释器

对于实例允许消毒类的名字:

class SomEFunk__YClAssName extends Controller 
{ 

} 

我需要某种形式的正则表达式将验证SomEFunk__YClAssName和消毒它如果需要的话!这也和方法一样。

有几件事情要考虑,如

  • Numerics的起步
  • 只是在强调允许允许
  • 某些PHP特殊字符。

关于这个或可能的表达式的任何信息将是非常有用的。

下面是我的一些路由器的代码,所以你可以看到我需要实现它:

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; 
    } 

你会看到需要检查的意见“消毒”。

回答

17

我相信你正在寻找的正则表达式是:

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

据:http://php.net/manual/en/language.oop5.basic.php

+0

感谢您的代码示例和文档链接。我会把这个标记为答案。 – Xunnamius 2013-06-16 03:50:59

+2

**注意**:我认为'preg_match'中存在一个缺陷,因为没有给出开始/结束分隔符。你的''input =“绝对不是一个有效的类名!”的代码将返回1.如果你把它改为'preg_match('/^[a-zA-Z_ \ x7f- \ xff] [a-zA-Z0- 9_ \ x7f- \ xff] * $ /',$ input);'返回0. – 2013-09-13 19:22:44

+0

开始/结束分隔符的良好调用。 – nate 2013-09-14 00:09:52

6

你最好使用一个非常普通的正则表达式,然后通过简单调用class_exists()来测试该类是否存在。

这将匹配任何有效的PHP类的名称,其中包括非常奇怪的像____3,这两者都是有效的类名:

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

我个人比PHP的命名约定上课更多的限制。我要求我的控制器被大写,并且用_controller后固定,以便不奇怪的非控制器类不会通过奇怪的URL调用。我会用这样的:

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

顺便说一句,通过查询字符串的产量真难看通过控制器名称和搜索引擎不友好的URL。考虑构建控制器名称和方法进入网址:

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

我想出了这样' ^(?= _ * [Az] +)[A-z0-9 _] + $'但仍然有字符,例如'class€1 {}'和'class€€_ {}' – RobertPitt 2010-07-07 14:34:59

+0

If你真的想调用任意命名的类,那么你所关心的就是这个类的存在。完全跳过正则表达式,它不会增加任何安全方面的东西,只需检查'class_exists()'。 – meagar 2010-07-07 14:39:54