在 CodeIgniter 模型方法中将一个数据库表行与来自另一数据库表的透视数据组合

问题描述 投票:0回答:2

我想组合来自两个单独查询的两个数组。我将产品存储在两个单独的表中:一个用于名称、描述、价格等一般信息;另一个用于存储基本信息。另一个是他们的各种细节,即服装尺寸和颜色。

所以我的产品数据库结构如下:

products table:
p_id | title | descr | etc

product_attrs table:
attr_id | products.p_id | name | value

其中名称和值可以是 name = Size value = Large

如果我尝试在一个查询中获取产品的所有详细信息,如下所示:

this->db->select('products.title,
                  p.description,
                  p.price,
                  p.stock,
                  p.name,
                  p.value');
$this->db->from('p');
$this->db->where('p.p_id', $id);
$this->db->join('product_attrs', 'product_attrs.product_id = p.p_id', 'inner');
$result = $this->db->get();
        
return $result->result_array();

我得到一个数组,其中填充了该产品的表product_attributes 中的名称/值对的数量。因此,如果产品有 5 个属性,我会像这样将所有内容返回 5 次:

Array (
    [0] => Array (
        [title] => Modest Swimsuit - Full body
        [description] => UV +50 Protection - Chlorine Resistant - Water Resistant - Quick Drying - Maximum Breathe Ability- Sea Water Resistant
        [price] => 59.95
        [stock] => 20
        [name] => Brand
        [value] => Modestly Active Swimwear
    )
    [1] => Array (
        [title] => Modest Swimsuit - Full body
        [description] => UV +50 Protection - Chlorine Resistant - Water Resistant - Quick Drying - Maximum Breathe Ability- Sea Water Resistant
        [price] => 59.95
        [stock] => 20
        [name] => Colour
        [value] => Black and Light Blue
    )
    [2] => Array (
        [title] => Modest Swimsuit - Full body
        [description] => UV +50 Protection - Chlorine Resistant - Water Resistant - Quick Drying - Maximum Breathe Ability- Sea Water Resistant
        [price] => 59.95
        [stock] => 20
        [name] => size
        [value] => small
    )
    [3] => Array (
        [title] => Modest Swimsuit - Full body
        [description] => UV +50 Protection - Chlorine Resistant - Water Resistant - Quick Drying - Maximum Breathe Ability- Sea Water Resistant
        [price] => 59.95
        [stock] => 20
        [name] => size
        [value] => medium
    )
    [4] => Array (
        [title] => Modest Swimsuit - Full body
        [description] => UV +50 Protection - Chlorine Resistant - Water Resistant - Quick Drying - Maximum Breathe Ability- Sea Water Resistant
        [price] => 59.95
        [stock] => 20
        [name] => size
        [value] => large
    )
)

所以我决定将每个表的查询分开,这样我每个表都可以获得一个结果集。但我想将它们结合起来,以便我可以将数据作为一个数组返回到控制器并将其显示到我的视图上。这就是我查询两个表的方式,我只需要一种方法来组合两个表的结果:

$this->db->select('p.title,
                   p.description,
                   p.price,
                   p.stock');
$this->db->from('p');
$this->db->where('p_id', $id);
$result = $this->db->get();
        
$this->db->select('name, value');
$this->db->from('product_attrs');
$this->db->where('p_id', $id);
$result2 = $this->db->get();

如果有人可以提供帮助,我将不胜感激。谢谢你

编辑:

我现在正在 php.net 中查看 array_merge() 函数,但如果我这样做:

$result = $this->db->get();
$array1 = $result->result_array();

$result2 = $this->db->get();
$array2 = $result2->result_array();
$data = array_merge($array1,$array2);
return $data;

我得到了多个数组:

Array (
    [0] => Array (
        [title] => Modest Swimsuit - Full body
        [description] => UV +50 Protection - Chlorine Resistant - Water Resistant - Quick Drying - Maximum Breathe Ability- Sea Water Resistant
        [price] => 59.95
        [stock] => 20
    )
    [1] => Array (
        [name] => Brand
        [value] => Modestly Active Swimwear
    )
    [2] => Array (
        [name] => Colour
        [value] => Black and Light Blue
    )
    [3] => Array (
        [name] => size
        [value] => small
    )
    [4] => Array (
        [name] => size
        [value] => medium
    )
    [5] => Array (
        [name] => size
        [value] => large
    )
)

有没有办法从我看来的上述数组中获取值?

php arrays codeigniter activerecord pivot
2个回答
2
投票

另一种选择是循环访问第二个结果数组并将值添加到第一个数组。

    // Get products results as an array
    $this->db->select('products.title,
                       products.description,
                       products.price,
                       products.stock');
    $this->db->from('products');
    $this->db->where('product_id', $id);
    $product = $this->db->get()->result_array();

    // Get product attributes as an array
    $this->db->select('name, value');
    $this->db->from('product_attributes');
    $this->db->where('product_id', $id);
    $product_attributes = $this->db->get()->result_array();

    // Loop through the results
    foreach($product_attributes as $attribute) {

         // Add results to original product array
         $product[$attribute['name']] = $attribute['value'];
    }

这应该产生一个像这样的数组:

        [title]       => Modest Swimsuit - Full body 
        [description] => UV +50 Protection - Chlorine Resistant - Water Resistant - Quick Drying - Maximum Breathe Ability- Sea Water Resistant 
        [price]       => 59.95 
        [stock]       => 20
        [Brand]       => Modestly Active Swimwear 
        [Colour]      => Black and Light Blue
        [size]        => small

0
投票

product_attrs
表中的数据需要“枢轴”来形成平面结构,但 CodeIgniter 没有任何开箱即用的东西,并且针对不同的数据库方言存在不同的可用技术。如果开发人员预先知道所需的属性名称,则此任务只能在 SQL / ActiveRecord 中完成。

为了保持一致且更易于管理,请在 PHP 中执行数据整合。从

$id
中选择
products
的单行数据,然后循环从
product_attrs
中获取的数据,并将名称-值对附加到原始产品行。

我通常会返回一个可为空的对象(以防所查找的行不存在),但因为您正在构建一个数组,所以我将违反我的正常编码约定并返回一个可为空的数组。

模型方法:(Mock Demo)

public function getProductDetailsById(int $id): ?array
{
    // fetch single row only
    $product = $this->db->select('title, description, price, stock')
        ->get_where('product', ['p_id', $id])
        ->row_array();

    // return early if not found
    if (!$product) {
        return null;
    }

    // fetch all related attribute rows
    $attributes = $this->db->select('name, value')
        ->get_where('product_attributes', ['p_id' => $id])
        ->result_array();

    // pivot and standardize dynamic attribute data
    $pivoted = [];
    foreach ($attributes as ['name' => $name, 'value' => $value]) {
        $name = strtolower($name);
        if (isset($pivoted[$name])) {
            $pivoted[$name] = (array) $pivoted[$name];
            $pivoted[$name][] = $value;
        } else {
            $pivoted[$name] = $value;
        }
    }

    // append pivoted data to product array
    return $product + $pivoted;
}
© www.soinside.com 2019 - 2024. All rights reserved.