Php WHILE语句,该语句需要多行代码来执行条件
下面的代码接收一个提议的用户名,如果未使用,则返回用户名;如果使用,则返回由最小整数追加的用户名。它工作得很好,但我只是忍不住想知道是否可以用一个单一的方法来完成。让我感到困惑的是WHILE语句需要Php WHILE语句,该语句需要多行代码来执行条件,php,Php,下面的代码接收一个提议的用户名,如果未使用,则返回用户名;如果使用,则返回由最小整数追加的用户名。它工作得很好,但我只是忍不住想知道是否可以用一个单一的方法来完成。让我感到困惑的是WHILE语句需要$stmt->execute(…)和return$stmt->fetchColumn()作为条件。我想匿名函数可以工作,但不要认为这将允许为每个调用使用准备好的语句。我认为DO循环可能会起作用,但我对它们没有太多经验,阅读暗示我应该“使用goto操作符而不是这个黑客。”请提供推荐的方法。谢谢 <
$stmt->execute(…)
和return$stmt->fetchColumn()
作为条件。我想匿名函数可以工作,但不要认为这将允许为每个调用使用准备好的语句。我认为DO循环可能会起作用,但我对它们没有太多经验,阅读暗示我应该“使用goto操作符而不是这个黑客。”请提供推荐的方法。谢谢
<?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));}
}
}
?>
就我个人而言,我会这样做:
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);
}
不知道这是否有效,如果你认为这不是一个好的方法,请投票否决(但请给出理由)。谢谢
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;
}
使用两种方法实际上更好,它使代码更可读,而单个方法更不复杂。@fab。有没有办法使用同一个prepared语句,而不是在每次调用第二个方法时重新创建它?并不是说我真的关心额外的时间,只是好奇而已。谢谢是的,将
$stmt
存储为私有属性,并且仅在它不存在时准备它(我会将此检查移到getUserNameStatement()
方法中),它们是您设置它的方式,效果很好,是我能想到的最好的实现,虽然如果找到用户名,我会修改make$I
random。或者,将SQL更改为SELECT username FROM username WHERE username WHERE username LIKE CONCAT(?“%”)
以返回已存在的用户名的所有前置变量,然后从中提取整数以执行“+1”操作。但在检查时,您还必须确保pass的用户名存在于返回中,并带有$name==$row['username']
类型的内容。这将添加更多代码,但用户基数较大,将显著减少查找工作用户名所需的SQL查询。不幸的是,此查询将不会使用用户名上的任何索引,这使得查询速度非常慢。True。这取决于碰撞的可能性。检查原始名称可能更好,如果发生冲突,则使用此正则表达式。谢谢Kolink,我不认为我会走这条路,但这是一个我甚至没有想到的解决方案,并且总是欣赏新的想法。