Question

What is the most efficient way of getting a product url given just it's ID? In a few places in our code we have things such as Mage::getModel('catalog/product')->load($id)->getProductUrl() in order to get the URL of the product, given the amount of events etc associated with a product this seems rather wasteful, is there a simpler method? The ability to also specify a category id would be nice.

Additionally, is there an efficient method for doing the same thing for a single attribute for a product such as name?

Was it helpful?

Solution

Interesting to know if we can get the product URL without loading whole product. Sorry to answer your additional question and not the main question, as I am also not sure if we can get it :)

For getting a single attribute without loading whole product, you can use getAttributeRawValue() if you are using Magento CE version 1.6+

Mage::getResourceModel('catalog/product')->getAttributeRawValue($productId, 'attribute_code', $storeId);

As per @philwinkle's comment below, here is more optimized code:

Mage::getResourceSingleton('catalog/product')
  ->getAttributeRawValue($productId, 'attribute_code', Mage::app()->getStore());

UPDATE: Get product URL by ID without loading whole product:

Mage::getResourceSingleton('catalog/product')
  ->getAttributeRawValue($productId, 'url_key', Mage::app()->getStore());

OTHER TIPS

I think it would be beneficial to do this via a collection. If you do not need the complete product information then you could load it via a collection and so only load information you need. The code would be as follows.

$product_collection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToFilter('entity_id', 16)
    ->addUrlRewrite();
$product_collection_url = $product_collection->getFirstItem()->getProductUrl();

Note: the addUrlRewrite so that you can get the product url later, this can also take a category id as a parameter, without this the url would not contain the category.

You are still end up calling the getProductUrl() which ends up using Mage_Catalog_Model_Product_Url, but this only needs the id, request_path and the url key so it should work without the full product.

I guess the most efficent way to get a products rewritten URL (w/o loading product) is to look directly on URL rewrite talbe.

# returns string "product-url.html"
$productUrl = Mage::getResourceModel('core/url_rewrite')
    ->getRequestPathByIdPath('product/' . $productId, $storeId);

To get full category path, use

# returns string "full/category/path/product-url.html"
$productUrl = Mage::getResourceModel('core/url_rewrite')
    ->getRequestPathByIdPath('product/' . $productId . '/' . $categoryId, $storeId);

Edit: tested for "url_key", for other attributes getAttributeRawValue should fit.

  1. getRequestPathByIdPath

    • Total Incl. Wall Time (microsec): 8,323 microsecs
    • Total Incl. CPU (microsecs): 8,038 microsecs
    • Total Incl. MemUse (bytes): 273,872 bytes
    • Total Incl. PeakMemUse (bytes): 213,488 bytes
    • Number of Function Calls: 372
  2. getAttributeRawValue

    • Total Incl. Wall Time (microsec): 51,213 microsecs
    • Total Incl. CPU (microsecs): 50,390 microsecs
    • Total Incl. MemUse (bytes): 1,223,520 bytes
    • Total Incl. PeakMemUse (bytes): 1,168,496 bytes
    • Number of Function Calls: 2,233
  3. load(productId)

    • Total Incl. Wall Time (microsec): 605,649 microsecs
    • Total Incl. CPU (microsecs): 598,820 microsecs
    • Total Incl. MemUse (bytes): 5,370,848 bytes
    • Total Incl. PeakMemUse (bytes): 5,314,384 bytes
    • Number of Function Calls: 27,774

I found this question, wondering the same. And just in case someone else needs this sometime, I'll post my own findings here.

I found two methods of getting the product URL without loading the complete product. Since I was working on a slow server, I needed to find the fastest loading method.

The first method:

The first get's a product collection based on the product ID:

$_item = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect('product_url')
    ->addAttributeToFilter('entity_id', $productId)
    ->addUrlRewrite()
    ->load();

foreach($_item as $product){
    echo $product->getProductUrl();
}

// returns string "http://www.your-domain.com/[category]/[product_url]"

The second method:

The second method, using Kalpesh Metha's method, would be this code:

Mage::getResourceSingleton('catalog/product')
      ->getAttributeRawValue($productId, 'url_key', Mage::app()->getStore());

// returns string "product-url-like-this"

For this method, you can either use 'url_key' or 'url_path'. I have not found out the difference though.

The difference between the methods:

The first method takes slightly more time (about 15% time extra). The second method however, only returns the final part of the URL. This means that if the shop uses the category in the URL, it won't work, since that part isn't shown. This was the case in the shop I was working on.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top