2013-02-09 28 views
0

以下內容會收到一個建議的用戶名,如果未使用,則返回用戶名,如果使用了用戶名,則返回最小整數。它工作正常,但我不禁想知道是否可以用單一方法完成。有什麼讓我難以置信的是WHILE聲明需要$stmt->execute(...)return $stmt->fetchColumn()作爲條件。我猜一個匿名函數可以工作,但不要認爲這將允許準備好的語句用於每個調用。我在考慮DO循環可能會起作用,但我沒有太多經驗,閱讀http://www.php.net/manual/en/control-structures.do.while.php意味着我應該「使用goto運算符而不是這種黑客。」請提供推薦的方法。由於WHILE需要多行代碼的條件

<?php 
    class myClass 
    { 
     public function createUsername($name) 
     { 
      $i=''; 
      while($this->openUsername($name.$i)==FALSE){$i=$i+1;} 
      return $name.$i; 
     } 
     private function openUsername($name) 
     { 
      $sql='SELECT id FROM users WHERE username=?'; 
      try 
      { 
       $stmt = db::db()->prepare($sql); 
       $stmt->execute(array($name)); 
       return $stmt->fetchColumn()?FALSE:TRUE; 
      } 
      catch(PDOException $e){die(library::sql_error($e,$sql));} 
     } 

    } 
?> 
+0

使用兩種方法實際上更好,它使代碼更具可讀性,單一方法更簡單。 – 2013-02-09 22:41:22

+0

@fab。每次調用第二個方法時,如何使用相同的準備好的語句而不是重新創建它?並不是說我真的很擔心額外的時間,只是好奇而已。謝謝! – user1032531 2013-02-09 22:43:18

+0

是的,存儲'$ stmt'作爲一個私人財產,並只准備它,如果它不存在(我會將此檢查到一個'getUserNameStatement()'方法) – 2013-02-09 22:45:49

回答

0

不知道這是否會工作,並請其否決(但請給評論爲什麼),如果你認爲它不是一個好的做法。謝謝

public function createUsername($name) 
{ 
    try 
    { 
     $i=''; 
     $sql='SELECT id FROM users WHERE username=?'; 
     $stmt = db::db()->prepare($sql); 
     do { 
      $stmt->execute(array($name.$i)); 
      $used=$stmt->fetchColumn()?TRUE:FALSE; 
      if(!$used) {$i=$i+1;} 
     } while ($used); 
    } 
    catch(PDOException $e){die(library::sql_error($e,$sql));} 
    return $name.$i; 
} 
0

個人而言,我應該這樣做:

function createUsername($name) { 
    // validate $name, for instance restrict to alphanumeric characters with preg_match 
    $sql = "SELECT GREATEST(`username`) AS `out` FROM `users` 
     WHERE `username` REGEXP '^".$name."\d*$'"; 
    $result = // whatever code it takes for PDO to run the above query 
    if(!$result) return $name; // nobody with that name yet 
    $number = preg_replace("^.*(\d*)$","$1",$result['out']); 
    if(!$number) return $name."1"; 
    return $name.($number+1); 
} 
+0

不幸的是,這個查詢不會在'username'上使用任何索引,這使得它非常慢。 – 2013-02-09 22:47:55

+0

是的。這取決於碰撞的可能性。檢查原始名稱可能會更好,如果發生碰撞,則使用此正則表達式。 – 2013-02-09 22:54:10

+0

謝謝Kolink,不要以爲我會走這條路,但這是我甚至沒有想到的解決方案,並且總是欣賞新的想法。 – user1032531 2013-02-09 23:01:19