简体   繁体   中英

Magento 1.7.0.2 - Call to member function getId() on a non-object in view.phtml (PHP Error)

I am intermittently receiving the following error when accessing the product detail pages on our Magento website...

Call to member function getId() on a non-object in view.phtml (line 70)

The code that this error is referencing to can be found below...

<?php
  $current_category = Mage::registry('current_category');
  $current_id = $current_category->getId();
?>

The reason I'm using the code there is to display content specific to products within those categories. An example can be seen below...

<?php if(($current_category) && ($current_id == 717)):?>
  // Code Here
<?php endif; ?>

I don't know why this error is coming about intermittently, or if there is a way to replace the code entirely with something else but get the same end result. I'm really up for either but would appreciate any and all assistance with the matter.

Thanks so much!

The registry is not a reliable place to get a product's category.

In the case of the product detail page, the entry point is the view action of the product controller: app/code/core/Mage/Catalog/controllers/ProductController.php::viewAction()

This action gets a product and category id from the url parameters (which are usually 'masked' by url keys). The category id is retrieved on line 119:

$categoryId = (int) $this->getRequest()->getParam('category', false);

The getParam function has 2 parameters. The first is required and is the name of the url parameter we are looking for. The second is optional and is the default value (what gets returned if that url parameter doesn't exist). So in this case, we are looking for the 'category' url parameter and returning its value, if it doesn't exist, we are returning false.

These values get passed to the prepareAndRender function of the product_view helper (line 132). This function lives in app/code/core/Mage/Catalog/Helper/Product/View.php. From there they get passed to the initProduct function of the product helper, which lives in app/code/core/Mage/Catalog/Helper/Product.php starting at about line 282.

This initProduct function is where we finally try to set that 'category_id' registry value. If we were able to get a category id from the url, that gets gets used to set the 'current_category' registry. If we didn't, then magento makes a last ditch effort and looks at the last category the customer looked at. If the current product is a member of that category, than we use it to set 'current_category'.

If we fail at both of those attempts, then we skip setting the 'current_category' registry all together.

The short of it is that if we access a product detail page with a url that does not contain the category (example.com/red-sofa instead of example.com/sofas/red-sofa) there is a pretty good chance that the 'current_category' registry key will not be set.

Since a product can have multiple categories, i would get the product model and call the getCategoryIds function, which will return an array of id numbers for all of the product's categories.

Your working in a template file the registry has the possibility of returning null, calling the registry is unneeded here, change your code to

<?php
    $this->getCurrentCategory()->getId();
?>

This is the proper way of calling a category id in a template file. If your working in a model or controller you will use Mage::getModel, or registry.

You can get category id and other data in the next way from the product:

$productCategories = $_product->getCategoryIds(); 
foreach ( $productCategories as $k => $_categoryId ){
$_category = Mage::getModel('catalog/category')->load($_categoryId) 
 echo $_category->getName()
}

Best Regards!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM