php 间接修改重载属性 App\Category::$thesizes 没有效果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38462131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Indirect modification of overloaded property App\Category::$thesizes has no effect
提问by Sven van den Boogaart
For a webshop im trying to generate a table that looks like:
对于网上商店,我试图生成一个如下所示的表格:
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
There is a table for each category, each category has his own sizes (table 2 has no size M for example). The tables show the amount of ordered products per size per product in each category.
每个类别都有一个表格,每个类别都有自己的尺寸(例如表 2 没有尺寸 M)。这些表格显示了每个类别中每个产品每个尺寸的订购产品数量。
In the application there is a model OrderProductswhich are ordered products in each Order.
在应用程序中有一个模型OrderProducts,它是每个Order中订购的产品。
An OrderProducthas a ProductSizewhich is a junction table of the product sizes
一个OrderProduct具有ProductSize这是产品尺寸的结合表
A ProductSizehas a Size(which contains the name of the size)
一个ProductSize有一个尺寸(包含尺寸的名称)
The first step im tryin to do is get all sizes/products for each category like:
我尝试做的第一步是获取每个类别的所有尺寸/产品,例如:
$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);
}
When I run my code I get the following error:
当我运行我的代码时,出现以下错误:
Indirect modification of overloaded property App\Category::$thesizes has no effect
间接修改重载属性 App\Category::$thesizes 没有效果
Why do I get this error and how should I solve it?
为什么会出现此错误,我该如何解决?
回答by Peter Bailey
This is because your Category
class has the __get()
and __set()
magic methodsimplemented.
这是因为您的Category
类实现了 the__get()
和__set()
magic 方法。
So line 7 ($cat->thesizes= array();
) invokes Category::__set()
and line 12 (array_push($cat->thesizes,$product->productSize);
) invokes Category::__get()
but notCategory::__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.
所以第 7 ( $cat->thesizes= array();
)Category::__set()
行调用,第 12 ( array_push($cat->thesizes,$product->productSize);
) 行调用Category::__get()
但不调用Category::__set()
。因此,虽然您为了将值推送到您在 Category 上设置的数组上而实现了这一点,但它不会工作,因为array_push()
它正在处理返回值而不是存储在 Category 中的实际数组。
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
有几种方法可以解决这个问题。最快捷的方法是更改Category::__get()
为通过引用返回值,这是通过在函数的返回声明中使用某种类型提示来完成的
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.
但是如果你好奇的话,我可能不推荐这样做。
The more sensible approach, without significantly modifying your code at least, is to build the arrays within the scope of the loop and thenadd them to your Category
objects
更明智的方法是至少在不显着修改代码的情况下构建循环范围内的数组,然后将它们添加到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);
}
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
如果你想获得奖励积分,因为这是 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();
});
回答by Santosh Kumar
Following trick has worked for me
以下技巧对我有用
public function methods(){
//other logics
...
$result = json_decode(json_encode($result));
$result->someProp = (object)[];
$result->someProp->another = 'test';
return response()->json($result);
}