我真的想说:不要尝试验证名称:总有一天,你的代码会遇到一个它认为“错误”的名称......当应用程序告诉他“你的名字”时,你认为人们会如何反应无效“?
根据您真正想要实现的目标,您可能会考虑使用某种黑名单/过滤器,以排除您想到的“非名字”:它可能会让一些“坏名字”通过,但至少,它不应阻止任何现有名称访问您的应用程序。
以下是一些想到的规则示例:
- 没有号码
- 没有特殊字符,比如
"~{()}@^$%?;:/*§£ø
可能还有其他一些
- 没有更多的3个空格?
- 没有“管理员”、“支持”、“版主”、“测试”以及人们在不想输入真实姓名时倾向于使用的其他一些明显的非名称......
- (但是,如果他们不想给你他们的名字,他们仍然不会,即使你禁止他们输入一些随机字母,他们也可以使用真实姓名......这不是他们的)
是的,这并不完美;是的,它会让一些非名字通过......但是对于你的应用程序来说,这可能比说某人“你的名字错了”要好得多(是的,我坚持 ^^)
而且,要回答您在另一个答案下留下的评论:
我可以禁止大多数命令字符用于 SQL 注入和 XSS 攻击,
关于 SQL 注入,您必须先对数据进行转义,然后再将其发送到数据库;而且,如果您总是转义这些数据(您应该!),您不必关心用户可能输入或不输入的内容:因为它被转义,所以始终对您没有风险。
XSS 也是如此:因为您在输出数据时总是会转义数据(您应该!),因此没有注入风险;-)
编辑:如果你只是像那样使用那个正则表达式,它就不会很好地工作:
以下代码:
$rexSafety = "/^[^<,\"@/{}()*$%?=>:|;#]*$/i";
if (preg_match($rexSafety, 'martin')) {
var_dump('bad name');
} else {
var_dump('ok');
}
至少会给你一个警告:
Warning: preg_match() [function.preg-match]: Unknown modifier '{'
您必须至少逃脱其中一些特殊字符;我会让你深入了解PCRE 模式以获取更多信息(关于 PCRE / regex 真的有很多要了解的;我无法解释这一切)
如果您真的想检查这些字符是否在给定的数据中,您可能会得到类似的结果:
$rexSafety = "/[\^<,\"@\/\{\}\(\)\*\$%\?=>:\|;#]+/i";
if (preg_match($rexSafety, 'martin')) {
var_dump('bad name');
} else {
var_dump('ok');
}
(这是一个快速而肮脏的命题,必须精炼!)
这个说“OK” (好吧,我绝对希望我自己的名字没问题!)
还有一些特殊字符的相同示例,如下所示:
$rexSafety = "/[\^<,\"@\/\{\}\(\)\*\$%\?=>:\|;#]+/i";
if (preg_match($rexSafety, 'ma{rtin')) {
var_dump('bad name');
} else {
var_dump('ok');
}
会说“坏名声”
但请注意,我还没有完全测试这个,它可能需要更多的工作!除非您非常仔细地测试过,否则不要在您的网站上使用它!
另请注意,在尝试执行 SQL 注入时,单引号可能会有所帮助...但它可能是在某些名称中合法的字符...因此,仅排除某些字符可能还不够 ;-)