Php 使用正则表达式验证类/方法名称

Php 使用正则表达式验证类/方法名称,php,regex,object,methods,Php,Regex,Object,Methods,我目前正在为一家公司开发一个MVC风格的框架,出于安全原因,我需要确保通过查询字符串传递的控制器/方法是RFC的有效字符(我找不到) 我需要能够根据PHP解释器允许的内容验证/清理类名 例如: class SomEFunk__YClAssName extends Controller { } 我需要某种正则表达式来验证SomEFunk\uuu YClAssName并在需要时对其进行清理!这也是与方法相同的原则 有几件事需要考虑,比如 开始时的数字 只允许下划线 允许使用某些PHP特殊字符

我目前正在为一家公司开发一个MVC风格的框架,出于安全原因,我需要确保通过查询字符串传递的控制器/方法是RFC的有效字符(我找不到)

我需要能够根据PHP解释器允许的内容验证/清理类名

例如:

class SomEFunk__YClAssName extends Controller
{

}
我需要某种正则表达式来验证
SomEFunk\uuu YClAssName
并在需要时对其进行清理!这也是与方法相同的原则

有几件事需要考虑,比如

  • 开始时的数字
  • 只允许下划线
  • 允许使用某些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;
    }

您将在需要检查的地方看到注释“Sanitize”。

最好使用非常通用的正则表达式,然后通过对
class\u exists()
的简单调用来测试该类是否存在

这将匹配任何有效的PHP类名,包括非常奇怪的类名,如
\uuuuu
\u3
,它们都是有效的类名:

/^[a-z_]\w+$/i
我个人比PHP的类命名约定更严格。我要求我的控制器大写,并用
\u 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。考虑在URL中建立控制器名称和方法:

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

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

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


根据:

我提出了这样做
^(?=.*[A-z]+)[A-z0-9+$
但是仍然有一些字符应该被允许,例如
类1{}
类€{}
如果你真的想调用任何任意命名的类,那么你真正关心的就是该类是否存在。完全跳过正则表达式,它不会添加任何安全方面的内容,只需检查
class\u exists()
。调用
class\u exists
将调用自动加载器。。并加载匹配的文件。。。这可能导致副作用。。在一个框架中(我将不命名),如果我“class_exists('index')”,它的自动加载程序将加载index.php。。这将尝试重新引导应用程序和致命错误谢谢您的代码示例和文档链接。注意:我认为你的
preg\u匹配中有一个缺陷,因为没有给出开始/结束分隔符。使用
$input=“绝对不是有效的类名!”
的代码将返回1。如果将其更改为
preg\u match('/^[a-zA-Z\ux7f-\xff][a-zA-Z0-9\ux7f-\xff]*$/',则为$input)返回0。很好地调用了开头/结尾分隔符。如果您想用命名空间验证类名,请使用以下命令:
/^[a-zA-Z\ux7f-\xff][a-zA-Z0-9\ux7f-\xff]*(\\\[a-zA-Z\ux7f-\xff][a-zA-Z0-9\ux7f-\xff]*)*$/
——区别仅在于使用反斜杠分隔符重复模式。PHP网站已更新为
\x80
,而不是
\x7f
<代码>^[a-zA-Z\uX80-\xff][a-zA-Z0-9\uX80-\xff]*$
对于@JosefKufner应答,反斜杠应为4。示例:
^[a-zA-Z\ux80-\xff][a-zA-Z0-9\ux80-\xff]*(\\\\[a-zA-Z\ux80-\xff][a-zA-Z0-9\ux80-\xff]*)$