2

我有以下函数来生成随机字符串:

public function generateString(){
    function generateCharacter () {
        $possible = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
        return $char;
    }
    function generateNumber () {
        $GUID = generateCharacter().generateCharacter().generateCharacter().generateCharacter().generateCharacter().generateCharacter().generateCharacter().generateCharacter().generateCharacter();
        return $GUID;
    }
    $string = generateNumber();
    return $string;
}

然后我需要能够使用 for 循环生成这些随机字符串 x 次并将它们插入我的 MySQL 表中:

$how_many是我选择要循环多少次的地方。

for ($i = 1; $i <= $how_many; $i++) {

        $random = $this->generateString();

        $query_params = array( 
            ':code' => $random,
        );
        $query = " 
            INSERT INTO table
            ( 
                code
            ) 
            VALUES 
            ( 
                :code
            )
        ";
        try { 
            $stmt = DB::get()->prepare($query); 
            $stmt->execute($query_params); 
        }  
        catch(PDOException $ex) {} 

    }

上面给了我一个错误:

Fatal error: Cannot redeclare generateCharacter() (previously declared in....

我知道我不能在 for 循环中使用该函数,否则我会收到此错误,但如果我将它放在循环之外,它只会生成一次字符串并每次插入相同的字符串。

我怎样才能得到它,所以我循环中的每个插入都是一个新的随机字符串?

4

3 回答 3

3

不要编写已经编写好的函数。

PHP 有一个叫做uniqid()的函数

从手册

uniqid() 根据当前时间(以微秒为单位)获取前缀唯一标识符。

uniqid() 返回的值将是 13 个字符长。如果 more_entropy 为TRUE,则​​为 23 个字符。

要获取随机数,您可以使用rand()函数。

在您的代码中,您在循环中多次准备相同的语句。这是非常坏的习惯。在循环之前准备语句,然后只在循环中执行和绑定参数。它更有效。

于 2013-06-24T10:53:07.987 回答
1

你可以试试更好:-

function generateString()
 {
  $number = base64_encode(openssl_random_pseudo_bytes(20, $strong));
  $newstr = preg_replace('/[^a-zA-Z0-9\']/', '', $number);
  return substr($newstr,0,10); return string of 10 random character 
 }
 ///same code after this
  for ($i = 1; $i <= $how_many; $i++) 
   {
    $random = $this->generateString();
    $query_params = array( 
        ':code' => $random,
    );
    $query = " 
        INSERT INTO table
        ( 
            code
        ) 
        VALUES 
        ( 
            :code
        )
    ";
    try { 
        $stmt = DB::get()->prepare($query); 
        $stmt->execute($query_params); 
    }  
    catch(PDOException $ex) {} 

}
于 2013-06-24T11:02:18.410 回答
0

我将尝试简要解释发生了什么,因此我将使用从技术角度来看可能不完全正确的术语。

在您的代码中,两个内部函数generateCharacter和在外部函数的主体generateNumber定义。generateString

最初,只有外部函数 ( generateString) 对您的其余代码“可用”。

当外部函数被调用时,它“定义”了两个内部函数,它们在全局范围内可用。即内部函数并不是真正私有的——它们被导出到全局,甚至不是类范围!

当您generateString多次调用外部函数时,内部函数会多次“定义”——就好像您将在全局范围内多次手动定义它们一样。这在 PHP 中是不允许的,因为错误。


可能的修复:

  • 将内部函数移动到全局范围内(无论如何,它们都会在第一次调用时导出)。这是最糟糕的方式。

  • 制作generateCharactergenerateNumber简单的私有方法。

  • uniqid按照其他答案中的建议使用PHP 。


这是一个简化的场景,看看会发生什么:

class Test {
  public function aaa() {
    function bbb() {
      echo("bbb");
    }
    echo "aaa";
    bbb();
  }
}

// bbb(); // would produce fatal error: undefined function bbb()
$test = new Test();
$test->aaa(); // outputs "aaabbb"
bbb(); // ok here, outputs "bbb"
于 2013-06-24T11:01:26.710 回答