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;
因为你推入了集合数组,所以首先你需要找到集合的有效键,然后你可以为这个键更新这个数组
经过大量谷歌搜索和 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;
因为你推入了集合数组,所以首先你需要找到集合的有效键,然后你可以为这个键更新这个数组