2012-01-28 143 views
1

我在php中使用preg_match_all来检查用户名和密码中的字符,然后将它们添加到数据库中,但似乎无法让它按照我想要的方式工作。以下是我现在所拥有的:PHP preg_match_all模式

preg_match_all(USERNAME_PATTERN,$username,$usernameMatches); 
preg_match_all(PASSWORD_PATTERN,$password,$passwordMatches); 

这里有图案,定义为常量:

/*Username and Password Patterns*/ 
define("USERNAME_PATTERN","[-*_a-z0-9A-Z.]"); 
define("PASSWORD_PATTERN","[_a-z0-9A-Z]"); 

我不知道什么是错的。它假设检查用户名是否具有a-z,A-Z,0-9,短划线,星号,下划线和句点之外的任何内容。密码与用户名相同。

这里是我用来检查代码:

if ($usernameMatches == 0){ 
echo("Bad characters in username<br />"); 
} 

的密码是一样的。

+2

为什么限制密码?无论如何,你只存储它们的哈希值。 – fuxia 2012-01-28 15:14:16

回答

3

有你的代码的几个问题。

  1. 您的regexes只匹配一个字符。
  2. 你的正则表达式中没有开始和结束的锚点。
  3. 请确保在调用preg_match_all()
  4. 你的正则表达式应该用/(或其他有效字符)包围之前实例化匹配阵列。
  5. 通过检查数组是否为空来检查不匹配,而不是通过检查它是否等于零来检查。 PHP中有许多类型/值检查陷阱,最好避免它们。

试试这个:

/*Username and Password Patterns*/ 
define("USERNAME_PATTERN","/^[-*_a-z0-9A-Z.]+$/"); 
define("PASSWORD_PATTERN","/^[_a-z0-9A-Z]+$/"); 

$usernameMatches = array(); 
$passwordMatches = array(); 

preg_match_all(USERNAME_PATTERN,$username,$usernameMatches); 
preg_match_all(PASSWORD_PATTERN,$password,$passwordMatches); 

if (empty($usernameMatches)){ 
    echo("Bad characters in username<br />"); 
} 

if (empty($passwordMatches)){ 
    echo("Bad characters in password<br />"); 
} 

BTW:你的代码可以通过简单地使用preg_match()代替preg_match_all()简化。像这样的东西应该工作以及你的代码:

/*Username and Password Patterns*/ 
define("USERNAME_PATTERN","/^[-*_a-z0-9A-Z.]+$/"); 
define("PASSWORD_PATTERN","/^[_a-z0-9A-Z]+$/"); 

if (!preg_match(USERNAME_PATTERN, $username)) { 
    echo("Bad characters in username<br />"); 
} 
if (!preg_match(PASSWORD_PATTERN, $password)) { 
    echo("Bad characters in password<br />"); 
} 
+0

目前无法测试,但是您是否还需要转义“。”,“*”和“ - ”? – 2012-01-28 15:19:42

+1

@Joachim Isaksson:不。点和星不是元字符,当他们在_角色class_中时。如果减号位于第一个或最后一个位置,则减号不是字符类中的范围元字符。 – Asaph 2012-01-28 15:26:14

+0

谢谢你,我已经改变为preg_match,并且正在使用你的方式,因为它确实更容易做到。 – legobear154 2012-01-28 15:33:13

2

使用此:

define("USERNAME_PATTERN","/^[-*_a-z0-9A-Z.]+$/"); 
define("PASSWORD_PATTERN","/^[_a-z0-9A-Z]+$/"); 

目前,您只允许单字符的用户名和密码。你也忘记了用/(或其他字符)封装正则表达式。 (诚​​然,这是针对PHP和其他一些语言的。)我还添加了^和$,以便整个输入字符串相匹配。

顺便说一句,为什么麻烦检查密码?只是需要一定的最小长度,例如(但不是在所有检查安全):

define("PASSWORD_PATTERN","/^.{6,}$/"); 

另外,我不知道为什么你使用preg_match_all。一个preg_match应该做的,以及,可能是更容易使用:

if (!preg_match(USERNAME_PATTERN, $username) { 
    echo("Bad characters in username<br />"); 
} 
+0

好的,谢谢。我可能只会限制密码的长度。 – legobear154 2012-01-28 15:16:26

+0

为什么限制长度?希望你不会以明文存储密码;你应该计算你存储在数据库中的密码的散列。即便如此,这被认为是不安全的。盐渍哈希是要走的路。 – robert 2012-01-28 15:19:10

+0

我正在加密密码。我也在腌制它。当我第一次这样做的时候,我真的不知道我脑子里经历了什么。感谢大家的帮助!任何人都可以点我一个很好的网站,学习如何创建主要用于PHP的模式? – legobear154 2012-01-28 15:25:41

1

不知道什么是错的。它假设检查用户名是否具有a-z,A-Z,0-9,短划线,星号,下划线和句点之外的任何内容。密码与用户名相同。

如果传递的用户名/密码有效,您应该检查。你需要这种模式。 /^[\-\*\w\d\.]{6,12}$/,这里最小和最大长度分别是6和12。

define('PATTERN', '/^[\-\*\w\d\.]+$/'); 
if(preg_match(PATTERN, $username)){ 
// username is correct 
} else { 
// username is wrong. 
} 

相同的密码。

1

在回答之前,我只想说通过问这个问题,我怀疑你是直接将密码保存为明文。这不是一个好的解决方案,因为它暴露了你的用户密码。有关围绕here的讨论,并举例说明如何以更安全的方式实现此目的。

作为一个额外的好处,无效字符(在密码中)的问题不会成为大多数情况下的问题,除非您正在处理一些遗留系统。原因是你不会存储实际的密码,但只是生成的散列

回到你的问题。我喜欢的另一种选择是检查任何无效字符的偏见。通过将^添加到字符列表中,您将匹配任何字符其他比列表。

define("USERNAME_PATTERN","/[^*_a-z0-9A-Z.-]/"); 
if(preg_match(USERNAME_PATTERN, $username)) 
    echo 'Bad characters in username';