laravel 对重载属性App\Category::$thesizes的间接修改无效

nxowjjhe  于 2022-12-01  发布在  Go
关注(0)|答案(4)|浏览(137)

对于一个网店,我试图生成一个如下所示的表:

Tablename: category 1
productname     S   M   L   X  total
name1           1    0  1   3  5
name2           0    1  0   2  3

Tablename: category 2
productname     S   L   X  total
name5           1   1   3  5
name8           0   0   2  2

每个类别都有一个表格,每个类别都有自己的尺码(例如,表格2没有尺码M)。表格显示了每个类别中每个产品的每种尺码的订购产品数量。
在应用程序中有一个模型OrderProducts,它是每个Order中的订购产品。
一个OrderProduct有一个ProductSize,它是产品大小的连接表

ProductSize有一个Size(包含尺寸名称)

第一步我尝试做的是获得所有尺寸/产品的每一个类别,如:

$order = Order::findOrFail($id);
    $products = OrderProduct::where('orders_id',$id)->get();

    $categories = Category::all();
    //get sizes and products per category
    foreach($categories as $cat)
    {
        $cat->thesizes= array();
        $cat->theprodcts= array();
        foreach($products as $product)
        {
            if($product->productSize->product->category_id == $cat->id)
            {
                array_push($cat->thesizes,$product->productSize);
                array_push($cat->theprodcts,$product);
            }

        }
        //make sure all values are unique (no dubbele sizes).
        $cat->theSizes = array_unique($cat->theSizes);
        $cat->theProducts = array_unique($cat->theProducts);
    }

当我运行代码时,出现以下错误:
对重载属性App\Category::$thesizes的间接修改无效
为什么会出现此错误?应该如何解决?

92dk7w1h

92dk7w1h1#

这是因为您的Category类实现了__get()__set()magic methods
因此,第7行($cat->thesizes= array();)调用Category::__set(),第12行(array_push($cat->thesizes,$product->productSize);)调用Category::__get() *,但没有调用 * Category::__set()。因此,尽管您实现了这一点,目的是将值推送到您在Category中设置的数组中,但它不会起作用,因为array_push()处理的是返回值,而不是存储在Category中的实际数组。
有几种方法可以解决这个问题。最快捷的方法是将Category::__get()更改为通过引用返回值,这是通过在函数的返回声明中使用sort-of type-hint来实现的

class Category
{
    public function &__get($key) {
        // body of function
    }
}

但这可能是不建议的原因,我可以进入如果你好奇。
更明智的方法是在循环范围内构建数组,* 然后 * 将它们添加到Category对象中,而至少不需要对代码进行重大修改

foreach ($categories as $cat) {
    // Scope local arrays here first
    $thesizes = array();
    $theproducts = array();

    foreach ($products as $product) {
        if ($product->productSize->product->category_id == $cat->id) {
            // Push to those local arrays
            array_push($thesizes, $product->productSize);
            array_push($theprodcts, $product);
        }
    }

    // Now assign them to the category object
    $cat->theSizes = array_unique($thesizes);
    $cat->theProducts = array_unique($theproducts);
}

如果您想获得额外的积分,因为这是Laravel,返回值是collections,您可以这样做,以获得更复杂的实现

$categories = (Category::all())->map(function(Category $cat) {
    $cat->theProducts = $products
        ->filter(function(Product $product) use ($cat) {
            return $product->productSize->product->category_id == $cat->id;
        })
        ->unique();

    $cat->theSizes = $cat->theProducts
        ->map(function(Product $product) {
            return $product->productSize();
        })->unique();
});
3b6akqbq

3b6akqbq2#

以下技巧对我很有效

public function methods(){
     //other logics
     ...
    $result = json_decode(json_encode($result));

    $result->someProp = (object)[];
    $result->someProp->another = 'test';

    return response()->json($result);
}
4dc9hkyq

4dc9hkyq3#

发生错误的原因是当您array_push到Category Object的Object时,尽管Field可能是一个数组,但它位于对象中,您必须将字段保存到数组变量,然后array_push到该变量,然后作为json字符串返回到字段

0yycz8jy

0yycz8jy4#

尝试使用如下自定义转换

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Foo extends Model
{
    protected $casts = [
        'bar' => 'collection',
    ];
}

然后,您可以更新或添加物料,如下所示:

$foo = Foo::find(1);

$foo->bar['a'] = 'b';
$foo->save();

相关问题