在foreach循环中的对象迭代中添加属性不起作用

时间:2016-08-22 04:31:42

标签: php silverstripe

我有以下代码

$products = Product::get()->filter(array("OwnerID" => $this->ParentID))->sort("Name");  

print_r($products->getIterator())输出跟随对象

ArrayIterator Object
(
    [storage:ArrayIterator:private] => Array
        (
            [0] => Product Object
                (
                    [destroyed] => 
                    [model:protected] => DataModel Object
                        (
                            [customDataLists:protected] => Array
                                (
                                )

                        )

                    [record:protected] => Array
                        (
                            [ClassName] => Product
                            [LastEdited] => 2013-06-15 12:19:54
                            [Created] => 2013-05-07 03:55:23
                            [Code] => 2348934-SBC-AVL
                            [Number] => 2348934
                            [Name] => Sewing Machine
                            [Model] => SBC-AVL
                            [ID] => 259
                            [RecordClassName] => Product
                        )
                )
        )
)  

问题

我希望在迭代它时修改对象product的{​​{1}}对象。我尝试使用以下代码

$products

我想将属性<?php public function getProducts(){ // First return all products by this parent id $products = Product::get()->filter(array("OwnerID" => $this->ParentID))->sort("Name"); if(!$products->count()) return false; foreach($products->getIterator() as $product) { $product->product_name="{$product->Name}"; $product->visible = true; } echo "<pre>".print_r($products,true)."</pre>"; exit; return $products; } product_name添加到visible对象。但不工作,如果我们打印product它输出原始输出。

问题 如何在$products的迭代中修改product对象并向其添加属性。我期待最终输出是 -

$products

4 个答案:

答案 0 :(得分:1)

如果$products->getIterator()是一个产品对象数组,那么您可以将其分配给另一个变量,并为其添加新的键,如

$modifiedPro = $products->getIterator();
foreach($modifiedPro as $key=>$product) {
    $modifiedPro[$key]->product_name="{$product->Name}";
    $modifiedPro[$key]->visible = true;
}
echo "<pre>".print_r($modifiedPro,true)."</pre>"; exit;

或者,您可以在对象之前使用&作为对象使用$product,例如,

foreach($products->getIterator() as &$product) {
    // -----------------------------^ here you need to use &
    $product->product_name="{$product->Name}";
    $product->visible = true;
}

添加&会使您的$products更新。要深入了解PHP foreach loopLanguage references

已更新,如果您使用的是PHP版本(&lt; 5.5),则可能会导致Cannot create references to elements of a temporary array expression之类的错误来解决您需要进行临时功能的此类错误

$a=products->getIterator();
foreach(z($a) as &$x) {
    $x->product_name="{$product->Name}";
    $x->visible = true;
}
print_r($a);

// indicate that this function returns by reference 
// and its argument must be a reference too
function &z(&$a)
{
    return $a;
}

我认为杰克已经在Is there a rational explanation for this PHP call-by-value behavior? Or PHP bug?

上做了很好的解释

答案 1 :(得分:1)

Rohan Kumar解释了如何以通用方式解决问题(使用基本的PHP方法)。由于您正在使用SilverStripe,因此可以利用框架来实现您的目标。

SilverStripes ViewableData对象具有customise方法,您可以使用该方法临时向对象添加其他字段。

以下是将附加字段添加到所有产品的方法:

public function getProducts()
{
    // First return all products by this parent id
    $products = Product::get()->filter("OwnerID", $this->ParentID)->sort("Name");

    if(!$products->count()) return null;

    $dataSet = [];
    foreach($products as $product) {
        $dataSet[] = $product->customise([
            'visible' => true,
            'product_name' => "{$product->Name}"
        ]);
    }

    return ArrayList::create($dataSet);
}

不知道为什么你需要这样做。我更愿意使用Product添加到Date添加想要的字段?这样您也可以访问其他地方的信息(例如Product-Detail-Page),而不仅仅是输出列表的位置。

答案 2 :(得分:0)

我解决了这个问题,更像是SilverStripe的方式。我接受了@ RohanKumar的回答,因为他的方式也适用。

$newProduct = new ArrayList();
 foreach($products->getIterator() as $product) {
        $product->product_name="{$product->Name}";
        $product->visible = true;
        $newProduct->push($product);
    }

return $newProduct;

答案 3 :(得分:0)

大家好,我尝试了所有解决方案,但在我的代码中对我有用的内容如下

$updatedProducts = $response['products'];
foreach($updatedProducts as $key=>$prd){

if(in_array($prd->sku, $bgxArrU)){
    $updatedProducts[$key]['isBgx']= TRUE;
}else{
    $updatedProducts[$key]['isBgx'] = FALSE;
}
 }
$response['products'] = $updatedProducts;