Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php WHILE语句,该语句需要多行代码来执行条件_Php - Fatal编程技术网

Php WHILE语句,该语句需要多行代码来执行条件

Php WHILE语句,该语句需要多行代码来执行条件,php,Php,下面的代码接收一个提议的用户名,如果未使用,则返回用户名;如果使用,则返回由最小整数追加的用户名。它工作得很好,但我只是忍不住想知道是否可以用一个单一的方法来完成。让我感到困惑的是WHILE语句需要$stmt->execute(…)和return$stmt->fetchColumn()作为条件。我想匿名函数可以工作,但不要认为这将允许为每个调用使用准备好的语句。我认为DO循环可能会起作用,但我对它们没有太多经验,阅读暗示我应该“使用goto操作符而不是这个黑客。”请提供推荐的方法。谢谢 <

下面的代码接收一个提议的用户名,如果未使用,则返回用户名;如果使用,则返回由最小整数追加的用户名。它工作得很好,但我只是忍不住想知道是否可以用一个单一的方法来完成。让我感到困惑的是WHILE语句需要
$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,我不认为我会走这条路,但这是一个我甚至没有想到的解决方案,并且总是欣赏新的想法。