Laravel collection 问题

Laravel collection issue

经过大量谷歌搜索和 Whosebug 搜索后,我决定需要你的帮助。

我必须获取某个供应商的每个供应的供应数量。我知道这听起来很奇怪,但让我解释一下:

我有一个 Supplier 模型,它有很多供应品,每个供应品都有很多库存,并且有一定数量。所以现在我正在构建一个视图,我想用它们在某个供应商上的数量来表示每个供应。

这就是我在控制器中想到的:

foreach ($suppliers as $supplier) {

        foreach($supplier->supplies as $supply){

            if(!$comp_supplies->contains('name', $supply->name)){

                $comp_supplies->push(['name'=>$supply->name, 'supplier'=>[['name'=> $supplier->name, 'quantity' => $supply->stocks->first()->quantity]]]);

            }elseif($comp_supplies->contains('name', $supply->name)){

                $array = (['name'=> $supplier->name, 'quantity' => $supply->stocks->first()->quantity]);
                $array2 = $comp_supplies->where('name', $supply->name)->first()['supplier'];

                array_push($array2, $array);

                //dd($array2);
                $comp_supplies->where('name', $supply->name)->first()['supplier'] = $array2;
                dd($comp_supplies->where('name', $supply->name)->first()['supplier']);
            }
        }

    }

所以我将遍历我的供应商并再次遍历他们每个人的供应。现在我想填充我想要的 collection 作为结果。

如果此 collection 不包含名称为“$supply->name”的供应,我将使用 supply-name 推送一个数组并创建一个数组 "suppliers",其中我还设置了当前供应商信息的第一个条目。

现在我们接近我的问题了。

如果 comp_supply 已经包含当前 supply-name 的供应,如果必须将新供应推入我们在第一个 [=58= 中创建的已经存在的 "supplier" 数组].

因此我创建了 $array,其中包含新的 supplier-informations,以及 $array2,其中包含 supplier-array ($comp_supplies->where('name', $supply->name)->first()['supplier']) 我们已经做了。

现在,如果我将 $array 推到 $array2 和 dd(array2) 上,一切都会按我想要的方式运行。 但是如果我现在设置

$comp_supplies->where('name', $supply->name)->first()['supplier'] = $array2 

然后是

dd($comp_supplies->where('name', $supply->name)->first()['supplier']);

没变。

我在这个问题上卡了将近 2 小时,真的很沮丧。

如果有人知道我可以做些什么来解决这个问题,或者知道我接下来可以去哪里,请告诉我。

这里还有迁移:

供应商:

public function up()
{
    Schema::create('suppliers', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name')->unique();
        $table->unsignedInteger('coordinates_id')->index()->nullable();
        $table->timestamps();
    });
}

耗材:

public function up()
{
    Schema::create('supplies', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->unsignedInteger('supplier_id');
        $table->foreign('supplier_id')
              ->references('id')
              ->on('suppliers')
              ->onDelete('cascade');
        $table->timestamps();
    });
}

个股:

    public function up()
{
    Schema::create('stocks', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('supplies_id');
        $table->foreign('supplies_id')
              ->references('id')
              ->on('supplies')
              ->onDelete('cascade');
        $table->integer('quantity');
        $table->timestamps();
    });
}

试试这个

$comp_supplies->where('name', $supply->name)->first()->update($array2)

而不是

$comp_supplies->where('name', $supply->name)->first()['supplier'] = $array2 

您的问题与 PHP 如何处理数组有关。数组是按值传递的,而不是按引用传递的,所以当你调用 $comp_supplies->where('name', $supply->name)->first() 时,你实际上得到了数组的一个副本,因此修改索引 'supplier' 处的值只会修改副本的值,不是原始数组的值。

您可以使用此示例代码验证此行为:

class TestList
{
    protected $values;

    public function push($value)
    {
        $this->values[] = $value;
    }

    public function get($index)
    {
        return $this->values[$index];
    }
}

$list = new TestList();
$list->push(['test' => 1]);

var_dump($list->get(0)['test']); // int(1)

$list->get(0)['test'] = 2;
var_dump($list->get(0)['test']); // still int(1)... 

您可以通过使用对象而不是数组来解决这个问题,因为对象是通过引用传递的(注意 (object) 转换):

$list = new TestList();
$list->push((object)['test' => 1]);

var_dump($list->get(0)->test); // int(1)

$list->get(0)->test = 2;
var_dump($list->get(0)->test); // int(2)!

而不是

$comp_supplies->where('name', $supply->name)->first()['supplier'] = $array2;

你应该使用:

$key = $comp_supplies->where('name', $supply->name)->get()->keys()->first();
$comp_supplies[$key]['supplier'] = $array2;

因为你推入了集合数组,所以首先你需要找到集合的有效键,然后你可以为这个键更新这个数组