代码之家  ›  专栏  ›  技术社区  ›  kojow7

PDO bindParam在循环中不工作

  •  0
  • kojow7  · 技术社区  · 7 年前

    我很难让bindParam在foreach循环中工作。如果我在循环外部使用bindParam,或者将值硬编码到sql查询中,那么一切都会很好地工作。根据 this page 建议改用bindValue。然而,当我使用bindValue时,它表示bindValue中使用的三个变量是未定义的。很明显,他们在这一点上。我做错了什么?

    <?php
    
        $found_update = false;
    
        $installed_groups = array(
            array(
                "group_id" => 14,
                "version" => "1.0.7"
            )
        );
    
    
    
        $sql = "select id from testing_set where group_id = :GROUP_ID
            and (
                substring_index(substring_index(version, '.', 2), '.', -1) > :INSTALLED_VERSION_NUM_1 OR
                substring_index(substring_index(version, '.', 3), '.', -1) > :INSTALLED_VERSION_NUM_2
            )
            order by created desc limit 1";
    
        try {
            $dbh = new PDO("mysql:host=localhost; dbname=".DBNAME, DBUSER, DBPWD);
    
                $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
                $stmt = $dbh->prepare($sql);
    
                $stmt->bindParam(":GROUP_ID", $installed_group['group_id'], PDO::PARAM_INT);
                $stmt->bindParam(":INSTALLED_VERSION_NUM_1", $installed_version_parts[1], PDO::PARAM_INT);
                $stmt->bindParam(":INSTALLED_VERSION_NUM_2", $installed_version_parts[2], PDO::PARAM_INT);
    
                foreach ($installed_groups as $installed_group){
    
                    $installed_version_parts = explode('.', $installed_group['version']);
    
                    $stmt->execute();
                    $data = $stmt->fetch(PDO::FETCH_ASSOC);
    
                    if (!empty($data)){
                        $found_update = true;
                        break;
                    }
            }
    
            echo "Found: $found_update\n";
    
        }
        catch(PDOException $e) {
            http_response_code(404);
            die();
    
        }
    

    我的预期结果是,它将向终端显示“找到:1”。现在的情况是,当它应该为真时,它的值为假。

    解决方案:

    原来这里有两个问题。我在bindParam中使用了基本变量而不是数组,从而遵循了IncremibleHat的答案。这有助于解决第一个问题,但另一个问题是我需要将一些数据类型转换为int:

    $pt1 = (int)$installed_version_parts[1];
    

    我以为 PDO::PARAM_INT 是为了我,但事实并非如此。

    1 回复  |  直到 7 年前
        1
  •  1
  •   IncredibleHat    7 年前

    正在尝试 bindParam 到数组元素,如 $array['key'] 导致一些问题,因为其绑定为引用,但不是。是的,只是没有那样做。

    所以有三种方法:

    $stmt = $dbh->prepare($sql);
    // bind to variables that can be a reference
    $stmt->bindParam(":GROUP_ID", $id, PDO::PARAM_INT);
    $stmt->bindParam(":INSTALLED_VERSION_NUM_1", $pt1, PDO::PARAM_INT);
    $stmt->bindParam(":INSTALLED_VERSION_NUM_2", $pt2, PDO::PARAM_INT);
    foreach ($installed_groups as $installed_group){
            $installed_version_parts = explode('.', $installed_group['version']);
            // assign the referenced vars their new value before execute
            $id = $installed_group['group_id'];
            $pt1 = $installed_version_parts[1];
            $pt2 = $installed_version_parts[2];
            $stmt->execute();
    }
    

    或:(效率较低)

    $stmt = $dbh->prepare($sql);
    foreach ($installed_groups as $installed_group){
            $installed_version_parts = explode('.', $installed_group['version']);
    
            // use bindValue (not bindParam) INSIDE the loop
            // bindValue doesn't set them by reference, so any value expression works
            $stmt->bindValue(":GROUP_ID", $installed_group['group_id'], PDO::PARAM_INT);
            $stmt->bindValue(":INSTALLED_VERSION_NUM_1", $installed_version_parts[1], PDO::PARAM_INT);
            $stmt->bindValue(":INSTALLED_VERSION_NUM_2", $installed_version_parts[2], PDO::PARAM_INT);
            $stmt->execute();
    }
    

    或:

    $stmt = $dbh->prepare($sql);
    foreach ($installed_groups as $installed_group){
            $installed_version_parts = explode('.', $installed_group['version']);
    
            // pass them on execute directly
            $stmt->execute(array(':GROUP_ID'=>$installed_group['group_id'],
                                 ':INSTALLED_VERSION_NUM_1'=>$installed_version_parts[1],
                                 ':INSTALLED_VERSION_NUM_2'=>$installed_version_parts[2]));
    }
    
    推荐文章
    Z Davies  ·  绑定参数错误
    9 年前