当您有相关产品并且启用了全页缓存时,产品页面上的错误


16

我在某些具有相关产品的产品上收到此错误:

Warning: Invalid argument supplied for foreach() in vendor/magento/module-catalog/Block/Product/ProductList/Related.php on line 129

仅在打开全页缓存时才会发生此问题。不幸的是,由于速度差异巨大(禁用页面缓存快2秒钟以上),因此不能选择禁用它。

我尝试了我所知道的一切:删除了主题,自定义模块等。

环境:生产,2.1.0,清漆。

这是完整的堆栈跟踪:

a:4:{i:0;s:190:"Warning: Invalid argument supplied for foreach() in vendor/magento/module-catalog/Block/Product/ProductList/Related.php on line 129";i:1;s:5441:"#0 vendor/magento/module-catalog/Block/Product/ProductList/Related.php(129): Magento\Framework\App\ErrorHandler->handler(2, 'Invalid argumen...', '/home/11396-492...', 129, Array)
#1 var/generation/Magento/Catalog/Block/Product/ProductList/Related/Interceptor.php(37): Magento\Catalog\Block\Product\ProductList\Related->getIdentities()
#2 vendor/magento/module-page-cache/Model/Layout/LayoutPlugin.php(71): Magento\Catalog\Block\Product\ProductList\Related\Interceptor->getIdentities()
#3 vendor/magento/framework/Interception/Interceptor.php(152): Magento\PageCache\Model\Layout\LayoutPlugin->afterGetOutput(Object(Magento\Framework\View\Layout\Interceptor), '    <script>\n  ...')
#4 var/generation/Magento/Framework/View/Layout/Interceptor.php(494): Magento\Framework\View\Layout\Interceptor->___callPlugins('getOutput', Array, Array)
#5 vendor/magento/framework/View/Result/Page.php(243): Magento\Framework\View\Layout\Interceptor->getOutput()
#6 vendor/magento/framework/View/Result/Layout.php(164): Magento\Framework\View\Result\Page->render(Object(Magento\Framework\App\Response\Http\Interceptor))
#7 vendor/magento/framework/Interception/Interceptor.php(74): Magento\Framework\View\Result\Layout->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#8 vendor/magento/framework/Interception/Chain/Chain.php(70): Magento\Framework\View\Result\Page\Interceptor->___callParent('renderResult', Array)
#9 vendor/magento/framework/Interception/Chain/Chain.php(63): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'renderResult', Object(Magento\Framework\View\Result\Page\Interceptor), Array, 'result-varnish-...')
#10 vendor/magento/module-page-cache/Model/Controller/Result/VarnishPlugin.php(74): Magento\Framework\Interception\Chain\Chain->Magento\Framework\Interception\Chain\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#11 vendor/magento/framework/Interception/Chain/Chain.php(67): Magento\PageCache\Model\Controller\Result\VarnishPlugin->aroundRenderResult(Object(Magento\Framework\View\Result\Page\Interceptor), Object(Closure), Object(Magento\Framework\App\Response\Http\Interceptor))
#12 vendor/magento/framework/Interception/Chain/Chain.php(63): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'renderResult', Object(Magento\Framework\View\Result\Page\Interceptor), Array, 'result-builtin-...')
#13 vendor/magento/module-page-cache/Model/Controller/Result/BuiltinPlugin.php(67): Magento\Framework\Interception\Chain\Chain->Magento\Framework\Interception\Chain\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#14 vendor/magento/framework/Interception/Chain/Chain.php(67): Magento\PageCache\Model\Controller\Result\BuiltinPlugin->aroundRenderResult(Object(Magento\Framework\View\Result\Page\Interceptor), Object(Closure), Object(Magento\Framework\App\Response\Http\Interceptor))
#15 vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'renderResult', Object(Magento\Framework\View\Result\Page\Interceptor), Array, 'aw_layerednav_r...')
#16 app/code/Aheadworks/Layerednav/Model/Plugin/Result.php(75): Magento\Framework\View\Result\Page\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#17 vendor/magento/framework/Interception/Interceptor.php(142): Aheadworks\Layerednav\Model\Plugin\Result->aroundRenderResult(Object(Magento\Framework\View\Result\Page\Interceptor), Object(Closure), Object(Magento\Framework\App\Response\Http\Interceptor))
#18 var/generation/Magento/Framework/View/Result/Page/Interceptor.php(130): Magento\Framework\View\Result\Page\Interceptor->___callPlugins('renderResult', Array, Array)
#19 vendor/magento/framework/App/Http.php(139): Magento\Framework\View\Result\Page\Interceptor->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#20 vendor/magento/framework/App/Bootstrap.php(258): Magento\Framework\App\Http->launch()
#21 index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))
#22 {main}";s:3:"url";s:15:"/pecan-pie.html";s:11:"script_name";s:10:"/index.php";}

有什么想法在哪里看?

在第129行中,n vendor/magento/module-catalog/Block/Product/ProductList/Related.php $this->getItems()为空:

  /**
     * Return identifiers for produced content
     *
     * @return array
     */
    public function getIdentities()
    {
        $identities = [];
        var_dump($this->getItems());
        foreach ($this->getItems() as $item) {
            $identities = array_merge($identities, $item->getIdentities());
        }
        return $identities;
    } 

谢谢!


您是否在模块中重写了Related.php?
Rakesh Jesadiya '16

@Rakesh不。只是一切。除了magento一和测试以外,没有其他相关课程。
Claudiu Creanga '16

1
似乎仅当缓存打开时才会发生此错误
Stevie G

1
因此,当您将产品视图从2列布局更改为单列布局时,会导致此错误
Stevie G

如果您有答案,请回答您的问题
Stevie G

Answers:


2

在同一Class(vendor/magento/module-catalog/Block/Product/ProductList/Related.php)中,有一种如下所示的方法。在此设置项目集合,然后在要调用的getItems()方法中使用它。在此处进行调试,并确认项目集合已得到一些结果。如您所见,此代码中已应用了一些过滤器,因此产品有可能没有通过这些过滤器。

/**
     * @return $this
     */
    protected function _prepareData()
    {
        $product = $this->_coreRegistry->registry('product');
        /* @var $product \Magento\Catalog\Model\Product */

        $this->_itemCollection = $product->getRelatedProductCollection()->addAttributeToSelect(
            'required_options'
        )->setPositionOrder()->addStoreFilter();

        if ($this->moduleManager->isEnabled('Magento_Checkout')) {
            $this->_addProductAttributesAndPrices($this->_itemCollection);
        }
        $this->_itemCollection->setVisibility($this->_catalogProductVisibility->getVisibleInCatalogIds());

        $this->_itemCollection->load();

        foreach ($this->_itemCollection as $product) {
            $product->setDoNotUseCategoryId(true);
        }

        return $this;
    }

1

只需在2.1.7 CE中击中此bug。

我有90%的把握是因为getIdentities()在_beforeToHtml()之前被“经常”调用。这意味着_prepareData()不会被调用,因此_itemCollection为空。这有点有意义,因为高速缓存要在生成html之前想知道什么(并且注意到getIdentites()与高速缓存相关)。

因此getIdentities需要调用_prepareData()

public function getIdentities()
{
    $this->_prepareData();

和_prepareData()需要防御两次运行。

protected function _prepareData()
{
    if($this->_itemCollection)
        return $this;

那一切都很好。

编辑:刚发现此已关闭的错误报告https://github.com/magento/magento2/issues/5897应该在以后的版本中修复。


0

您可以尝试将以下内容添加到定义此布局块的模板布局文件中:

<action method="unsetData"><key>cache_lifetime</key></action>
<action method="unsetData"><key>cache_tags</key></action>

像这样将其添加到块的顶部:

<module_index_index>
     <action method="unsetData"><key>cache_lifetime</key></action>
     <action method="unsetData"><key>cache_tags</key></action>
     // the actions that are defined
</module_index_index>

上面的代码表示您不会缓存此布局块。

如果这样做有效,则意味着缓存将不允许您保留数据,还是被其他东西覆盖而使其为空?(在这里猜)


-4

试试这个代码:

$model = Mage::getModel('catalog/product');
$product = $model->load($product_id);

// Get all related product ids of $product.
$allRelatedProductIds = $product->getRelatedProductIds();

foreach ($allRelatedProductIds as $id) {
            $relatedProduct = $model->load($id);

            // get Product's name
            echo $relatedProduct->getName();

            // get product's short description
            echo $relatedProduct->getShortDescription();

            // get Product's Long Description
            echo $relatedProduct->getDescription();

            // get Product's Regular Price
            echo $relatedProduct->getPrice();

            // get Product's Special price
            echo $relatedProduct->getSpecialPrice();

            // get Product's Url
            echo $relatedProduct->getProductUrl();

            // get Product's image Url
            echo $relatedProduct->getImageUrl();

        }

这是magento1
Claudiu Creanga

-6

我们遇到了这个问题。检查产品(不是相关产品)是否缺货。将产品放入库存可以为我们解决问题。


但是,这不能解决问题,可以避免问题
Stevie G

这不是解决方案
哈里(Harri)'17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.