且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-11-19 17:39:28

这是因为您的 Category 类具有 __ get() __ set()已实现魔术方法.

This is because your Category class has the __get() and __set() magic methods implemented.

因此第7行( $ cat-> thesizes = array(); )调用 Category :: __ set()和第12行( array_push($cat-> thesizes,$ product-> productSize); )调用 Category :: __ get() 但不是 Category :: __ set().因此,尽管您打算将值推送到在类别"上设置的数组上来实现此目的,但由于 array_push()正在处理返回值而不是存储在其中的实际数组,因此它不起作用类别.

So line 7 ($cat->thesizes= array();) invokes Category::__set() and line 12 (array_push($cat->thesizes,$product->productSize);) invokes Category::__get() but not Category::__set(). So while you impelemented this with the intention of pushing values onto an array that you set on the Category, it won't work since array_push() is working on a return value and not the actual array stored in the Category.

有几种方法可以解决此问题.最快捷的方法是将 Category :: __ get()更改为通过引用返回值,这是通过在函数的返回声明上使用某种类型的提示来完成的

There are a few ways to fix this. The most shortcut way is to change Category::__get() to return values by reference, which is done by using a sort-of type-hint on the function's return declaration

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

但是,出于您好奇的原因,我可能不建议您这样做,因此不建议这样做.

But this is probably not recommended for reasons I can go into if you're curious.

更明智的方法是至少在循环范围内构建数组,然后至少将其修改,然后将它们添加到您的 Category 对象中

The more sensible approach, without significantly modifying your code at least, is to build the arrays within the scope of the loop and then add them to your Category objects

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,您的返回值为收藏,您可以执行类似的操作来实现更复杂的实现

If you want to go for bonus points, since this is Laravel and your return values are collections, you can do something like this for a more sophisticated implementation

$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();
});