foreach 循环的迭代问题

Posted

技术标签:

【中文标题】foreach 循环的迭代问题【英文标题】:iteration problems with foreach loop 【发布时间】:2015-02-16 21:56:23 【问题描述】:

我正在尝试创建一个创建 sql 语句以将数据插入数据库的函数,这是一个 sn-p。除了最后一个 foreach 循环外,它工作正常。由于某种原因,它不会迭代到数组中的最后一个元素,它会停留在倒数第二个元素上。问题是第一个 foreach 循环是相同的代码并且工作正常,但第二个给我带来了麻烦。

*注意:foreach 循环中的 if 语句应该捕获数组中的最后一个元素,并确保没有插入“,”。这就是问题所在。如果我将 if 语句从第二个循环中取出,循环将迭代到最后一个元素,但没有 if 块,它会在末尾放置一个逗号并创建 SQL 语法错误。

第一个循环的输出

INSERT INTO gardyloo.users (joe,bob,joe@hotmail.com,8de,154927,2014-12-18,2014-12-18 7:02:11)

没有if的第二个循环的输出

VALUES (:firstName,:lastName,:emailAddress,:password,:userid,:date_joined,:timestamp,)

第二个循环的输出 if

VALUES (:firstName,:lastName,:emailAddress,:password,:userid,:date_joined)  

foreach( $values as $a => $b )

        if(next($values) == null)
            $sql .= $b."";
            break;
        
        $sql .= $b.",";
    
    $sql .= ") ";
    $sql .= "VALUES (";
    foreach( $values as $a => $b )

        if(next($values) == null)
            $sql .= ":".$a;
            break;
        
        $sql .= ":".$a.",";
    
$sql .= ")";

*编辑,这段代码似乎工作正常:

$sql .= implode(', ', array_keys($values));
$sql .= ") ";
$sql .= "VALUES (:";
$sql .= implode(", :", array_keys($values)); 
$sql .= ")";    

【问题讨论】:

你不应该在生产环境中这样做。您正在向SQL Injection 攻击敞开大门。始终使用参数化语句。 参数化语句是什么意思? en.wikipedia.org/wiki/Prepared_statement 我应该在 $sql .= ")";是 $query = $init->link->prepare($sql);这意味着什么? 我对 php 不是很熟悉,但基本上,我会推荐以下内容: $query = $init->link->prepare("INSERT INTO gardyloo.users VALUES(?,?, ?,?,?,?,?)");然后,运行一个 for 循环(如果要添加多行,否则没有 for 循环)来运行查询 $query->execute($firstName, $lastName, $emailAddress, $password, $userId, $dateJoined, $timestamp); 【参考方案1】:

你需要使用 continue 而不是 break; Break 中断循环,而 continue 只移动到下一次迭代。

试试这个:

foreach( $values as $a => $b )

    if($b == null)
        continue;
    
    $sql .= ":".$a.",";

【讨论】:

这似乎不起作用。它确实有助于迭代到最后一个元素,但它做得不好。【参考方案2】:

做这样的事情:

       //Your data 
       $values = array(
                       'firstName'    => 'Joe', 
                       'lastName'     => 'bob', 
                       'emailAddress' => 'joe@hotmail.com', 
                       'password'     => '8de', 
                       'userid'       => 154927, 
                       'date_joined'  => '2014-12-18', 
                       'timestamp'    => '2014-12-18 7:02:11'
                       );

        //Begins the sentence
        $sql    = 'INSERT INTO gardyloo.users(';

        /**
         * Begins example code.
         * - array_keys shows the key as a value
         *   example: $values[0] = firstName
         */
        foreach(array_keys($values) as $k => $v)
        
            //when the array arrives at the end, doesn't show ','
            if($k != count($values)-1)
                $sql .= $v.",";
            else
                $sql .= $v;
        

        $sql .= ") ";
        $sql .= "VALUES (";
        $k = 0;//the new count initialized

        foreach($values as $v)
        
            //when the array arrives at the end, doesn't show ','
            if($k != count($values)-1)
                $sql .= $v.",";
            else
                $sql .= $v;
            //increments the counter
            $k++;
        

        $sql .= ");";

注意事项:

将函数中的代码分开,因为两个 foreach 非常相似。 您可以使用 foreach 值来返回您想要的值。 如果您对此有更多疑问,请咨询我。

【讨论】:

【参考方案3】:

否则我会这样做。而不是 concat a string $sql 创建 2 个变量 $columns 和 $values,它们都是数组。而且您不需要循环来执行此操作。

所以我会这样做:

$columns = array_keys($values);

$sql = "INSERT INTO table (". implode(" ,", $columns) . ") VALUES (". implode(" ,", $values);

这里你不需要测试它是否是数组的最后一个元素来制作break;

希望对你有帮助;)

【讨论】:

以上是关于foreach 循环的迭代问题的主要内容,如果未能解决你的问题,请参考以下文章

foreach 循环,判断哪个是循环的最后一次迭代

使用 forEach 循环执行每次迭代后添加延迟

如何在刀片foreach循环中获取迭代次数

在每个 foreach 循环迭代中包含重复的刀片模板

foreach 循环是不是从字面上重写为带有迭代器的 for 循环? [复制]

转到 JavaScript forEach 循环中的“下一个”迭代 [重复]