这里有一个奇怪的人。
我正在使用一个函数为令牌生成随机的字符字符串:
private static function generatePasswordResetCode()
{
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-';
return substr(str_shuffle($chars), 0, RESET_TOKEN_LENGTH);
}
RESET_TOKEN_LENGTH
是一个常量:
define("RESET_TOKEN_LENGTH", 100);
代码像这样保存到表中:
$code = self::generatePasswordResetCode();
$expiry_timestamp = time() + RESET_CODE_EXPIRY_TIME;
$sql = "INSERT INTO reset_codes (code, user_id, expires_at)
VALUES (:code, :user_id, :expires_at)";
$db = static::getDB();
$stmt = $db->prepare($sql);
$stmt->bindParam(':user_id', $id, PDO::PARAM_INT);
$stmt->bindParam(':code', $code, PDO::PARAM_STR);
$stmt->bindValue(':expires_at', date('Y-m-d H:i:s', $expiry_timestamp), PDO::PARAM_STR);
$stmt->execute();
在数据库中,code
列设置为varchar(255)
。我也尝试过text
,但无论哪种方式,我都遇到相同的问题。
无论我将RESET_TOKEN_LENGTH
定义为不超过63个字符,一切正常,但是任何大于该数字的字符串都将在code
列中被截断:
define("RESET_TOKEN_LENGTH", 63);
// results in
MFYflHL6bVwNEG1DpqRA0ry5TgC9KhmntPUao2x-ujvekX7sZcQizWSd43OBIJ8
很好,但是...
define("RESET_TOKEN_LENGTH", 64);
// results in
7fITjSp32gmA0YJCwFhrWvPk4VDQMZonl19btBKs5Ri-zULeXO...
任何想法可能是什么原因造成的?
****更新****
因此,这似乎与MySQL不相关,但与PHP相关。
substr
和str_shuffle
的组合似乎限制了63个字符,无论您定义的数字超过63个字符。
为了测试它,我像这样改变了功能:
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-';
$code = substr(str_shuffle($chars), 0, RESET_TOKEN_LENGTH);
$code2 = substr(str_shuffle($chars), 0, RESET_TOKEN_LENGTH);
$code = $code . $code2;
return $code;
将得到正确的var_dump
输出:
define("RESET_TOKEN_LENGTH", 50);
//results in
string(100) "fk8DcbusUeVxWOdp1HwNLEy9gzYm6tq0o3PMaZAIh2Sn45F-K7GH9l18hZNk73j6cQpFDfPwxMCe4BTrqiIASdRs5WEnoKgmzyXY"
正在做什么:
define("RESET_TOKEN_LENGTH", 64);
//results in
string(126) "Q14Hd0WJjVotYRfsaU5pAM7DeZSuvwnCmxqbPgh6839XrEIyBcKTONzG-kil2FL0LUgQG8452WqKEfdmuzHlr9PZevc7VhnNCSjbk-wTyMR1iOspxaXYJDoFtBIA36"
显示$code
和$code2
被截断为63个字符。
非常奇怪!
**更新2 **
[我似乎对str_shuffle
的运作方式缺乏了解在这里是错,没有其他。请参阅下面接受的答案。
这与数据库或PDO无关。您的$chars
长为63个字符,str_shuffle
只是将周围的字符串中的字符混排。 63个字符串,不能超过63个字符。
您可能更希望查看PHP random string generator以解决您的问题。