PHP中合法变量名的字符串清理

3

我有类似下面这样的代码,声明了一个类,它的名称基于一个检索到的字符串。但问题是该字符串可能包含PHP不接受作为类名的非法字符。因此,在将其用作类名之前,是否有一种好的方法来清理字符串?

$retrieved_string = 'some unformatted string; it may contain illegal characters to be passed as a class name.';

$strMyScript = basename(__FILE__, ".php"); 
$strMyScript = sanitize_variable($strMyScript);
$strClassName = sanitize_variable($retrieved_string);

eval('
    class ' . $strMyScript . '_' . $strClassName . ' extends AnotherClass {
        // some code here
    }
');

funaction sanitize_variable($string) {
    // sanitize the string
}

将其与以下正则表达式进行匹配:[_a-zA-Z][_a-zA-Z0-9]* - user529758
3个回答

2
您可以使用以下方式检查字符串是否为有效的标识符(类、变量或函数名):
if (preg_match("/^[_a-zA-Z][_a-zA-Z0-9]*$/", $received_string)) {
    // valid name
} else {
    // invalid name
}

1

PHP作者提供了一个正则表达式,请参见类的手册条目

<?php

if (preg_match('/^([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$/', $strClasssName)) {
    // etc.
}

对于函数名称或任何其他标签都是一样的。

如果您想要清理字符串,那么也许您需要删除除了[a-zA-Z0-9_\x7f-\xff]之外的所有内容,然后根据^([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$进行验证(区别在于,虽然允许整数字符,但类/函数名称可能不以数字开头)。


preg_match('/^([\w\d_\x7f-\xff][\w\d_\x7f-\xff]*)$/', $strClasssName, $match)) -- 用于字符串捕获... - marklark
\w 包含 \d_,所以不需要将它们包含在内。其次,标签不能以 \d 开头,因此第一个字符不能是 \w。另外,您可能想要使用 u(Unicode)修饰符。 - Alexei

1

首先决定您需要过滤器还是验证器。验证器将返回真/假。然后您可以引发异常,为用户生成错误或仅忽略文件。另一个选项是使用过滤器,它将有效地从输入字符串中删除字符。

public function sanitize($input)
{
    $pattern = '/[^a-zA-Z0-9]/';

    return preg_replace($pattern, '', (string) $input);
}

您可能还想检查 Unicode。模式为:
public function sanitize($input)
{
    if (!@preg_match('/\pL/u', 'a'))
    {
        $pattern = '/[^a-zA-Z0-9]/';
    }
    else
    {
        $pattern = '/[^\p{L}\p{N}]/u';
    }
    return preg_replace($pattern, '', (string) $input);
}

还需要考虑以下问题:

  • 您是否想启用空格支持?如果是,则需要在$pattern变量中添加一个空格。
  • 文件名是否使用非英语语言?那么您需要进行一些特定于区域设置的操作,以使$pattern保持最新状态。

希望对您有所帮助


似乎我的最后一条评论已被删除或无法提交。我从未考虑过可能包含Unicode字符串。谢谢提醒。我会寻找另一种方法,比如使用uniqid()生成一个唯一的ID,根据文件修改日期,这样我就不需要过滤字符串了。感谢大家的回答。 - Teno
1
我认为您的意思是:返回preg_replace($pattern, '', (string) $input);(而不是$value)。 - Jiminy Cricket
好的发现!谢谢@JiminyCricket - Nikolaos Dimopoulos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接