Php PDO查询中的Foreach生成语句

Php PDO查询中的Foreach生成语句,php,pdo,Php,Pdo,我正在将旧的查询转换为PDO准备的语句,但是我仍然停留在使用foreach循环填充未知数量条件的动态查询的一部分 以下是查询这一部分的示例(值为多个): 具有总和(li.MSAttributeValID IN(5))>0和 总和(li.MSAttributeValID IN(224234240))>0 以及通过在数组中循环生成它的代码: if($filterArray['Attributes']){ $this->sql_part_2 .= " having &q

我正在将旧的查询转换为PDO准备的语句,但是我仍然停留在使用foreach循环填充未知数量条件的动态查询的一部分

以下是查询这一部分的示例(值为多个):

具有总和(li.MSAttributeValID IN(5))>0和 总和(li.MSAttributeValID IN(224234240))>0

以及通过在数组中循环生成它的代码:

if($filterArray['Attributes']){
        $this->sql_part_2 .= " having ";
        foreach($filterArray['Attributes'] as $attID => $attValueArray){
            if($attID == array_key_first($filterArray['Attributes'])){
                $this->sql_part_2 .= " SUM(";
            }
            $this->sql_part_2 .= "li.MSAttributeValID IN (";
            foreach($attValueArray as $attValueID => $attValue){
                $this->sql_part_2 .= "$attValue";
                if($attValueID != array_key_last($attValueArray)){
                    $this->sql_part_2 .= ",";
                }else{
                    $this->sql_part_2 .= ")) > 0";
                }
            }
            if($attID != array_key_last($filterArray['Attributes'])){
                $this->sql_part_2 .= " AND SUM(";
            }
        }
    }
$filterArray:

[Attributes] => Array
            (
                [82] => Array
                    (
                        [0] => 6
                        [1] => 7
                    )

                [85] => Array
                    (
                        [0] => 231
                    )

            )
在此实例中,我将如何设置参数?我可以对循环中的变量进行计数吗?不知道从哪里开始,我应该读什么来涵盖这个场景?多谢各位

通过以下方式绑定/执行:

    $sql_results = $pdo->prepare($this->select_products_sql.$this->sql_part_1.$this->sql_part_1a.$this->sql_group.$this->sql_part_2.$this->sql_sort.$limit);

    $sql_results->bindValue(':CategoryID', $this->SubCategoryID);
    $sql_results->bindValue(':PriceMin', $PriceMin);
    $sql_results->bindValue(':PriceMax', $PriceMax);
    $sql_results->bindValue(':limitFrom', $limitFrom, PDO::PARAM_INT);
    $sql_results->bindValue(':limitTo', $limitTo, PDO::PARAM_INT);

    $sql_results->execute();

    $results = $sql_results->fetchAll();

这段代码应该满足您的要求。对于每组数据,它将创建一个新的占位符并为您绑定值。 我已经尽了最大的努力来评论这些行,让你更好地理解正在发生的事情

if($filterArray['Attributes']){
    
    //create an empty array which will eventually hold each SUM() call for your query
    $attributes = [];
    
    //create an empty array to hold values you need to bind with the placeholder as the key
    $attribute_binds = [];
    
    //loop through all sets of attributes
    foreach($filterArray['Attributes'] as $key => $values) {
        
        // ... for each set of attributes
        
        //create empty array for placeholder names
        $placeholders = [];
        
        //loop through each value of set
        foreach($values as $key2 => $value) {
            
            //create a placeholder name unique to this attribute data
            //e.g `attribute_82_0` based on keys of each data set
            //by using array keys this way, each placeholder will be unique
            //add placeholder name and value to $attribute_binds array
            //add placeholder name to $placeholders array
            $placeholder_name = ":attribute_{$key}_{$key2}";
            $attribute_binds[$placeholder_name] = $value;
            $placeholders[] = $placeholder_name;
        }
        
        //implode $placeholders array to be a comma separated list
        $placeholders = implode(', ', $placeholders);
        
        //add completed attribute SUM() call to $attributes array
        $attributes[] = "SUM(li.MSAttributeValID IN ({$placeholders})) > 0";
    }
    
    //implode all SUM() calls to your query
    $this->sql_part_2 .= implode(' AND ', $attributes);
}

//later in the script, prepare and bind values
$sql_results = $pdo->prepare($this->select_products_sql.$this->sql_part_1.$this->sql_part_1a.$this->sql_group.$this->sql_part_2.$this->sql_sort.$limit);

$sql_results->bindValue(':CategoryID', $this->SubCategoryID);
$sql_results->bindValue(':PriceMin', $PriceMin);
$sql_results->bindValue(':PriceMax', $PriceMax);
$sql_results->bindValue(':limitFrom', $limitFrom, PDO::PARAM_INT);
$sql_results->bindValue(':limitTo', $limitTo, PDO::PARAM_INT);

//bind attribute values
foreach($attribute_binds as $placeholder => $value) {
    $sql_results->bindValue($placeholder, $value);
}

$sql_results->execute();
在上面的代码中,给定示例数据,以下字符串将附加到
$this->sql\u part\u 2
,并且这些值将绑定到唯一的占位符名称

SUM(li.MSAttributeValID IN (:attribute_82_0, :attribute_82_1)) > 0 AND SUM(li.MSAttributeValID IN (:attribute_85_0)) > 0

你能给我们看一下
$filterArray['Attributes']
看起来像什么样的示例吗?嗨,坏脾气,我在我的线程中添加了一个示例。它总是两组数据吗?不,它是一个未指定的数量,可以是1,2,3,4。。。。取决于最终用户选择的标准。因此,对于每个数据集,它都需要自己的
SUM()
?您好@GrumpyCrouton,回答得很好,非常感谢,这很有意义。我只是不知道如何像平常一样将值绑定到这个数据集?占位符。我已经用绑定/执行部分编辑了我的原始帖子,谢谢你的帮助。谢谢你的耐心,这很有意义!我假设“$VAL”需要是$filterArray['Attributes'],那么在准备之前如何绑定值?因为prepare是变量的组合,而不是SQL,所以我需要在最后使用它。因此,此循环中bindValue的$sql_结果未定义。@nicksource请再次检查我的更新。我改变了一些事情