1. 程式人生 > >解決magento批量assign產品到分類時最多隻能save成功1000件的問題

解決magento批量assign產品到分類時最多隻能save成功1000件的問題

注 :文章中問題已在Magento EE 1.14 / CE 1.9得到驗證。

最近,我發現了一件非常奇怪的問題。當為一批產品(大於1000件)分配分類時,只有最多一千件產品能夠儲存成功,而其他的都被忽略了。為了解決這個問題,就需要我們去深入magento的原始碼進行分析測試。

下面是Magento如何分配產品類別的原始碼:

class Mage_Adminhtml_Catalog_CategoryController extends Mage_Adminhtml_Controller_Action
{
public function saveAction()
{
. . .
 
if (isset($data['category_products']) && !$category->getProductsReadonly()) {
$products = array();
parse_str($data['category_products'], $products);
$category->setPostedProducts($products);
}
. . .
}
}

$data[‘category_products’]是一個產品序列的字串,通過parse_str生成一個關聯陣列將產品儲存的一個數組中。但是但從這段程式碼,並沒有看出哪裡不對,再去error log裡檢查下,於是發現有如下的警告:
Warning: parse_str(): Input variables exceeded 1000. To increase the limit change 
max_input_vars in php.ini.

如你所看到的,這個問題是由於PHP的配置引數max_input_vars引起的,因為php限制了可以接受的輸入變數的數量。在PHP版本5.3.9 的說明裡有介紹,大致是為了避免雜湊衝突, Parse_str對引數數量進行了限制。結果陣列的長度大於或者等於1000時,預設只取1000個,這就是為什麼只有一個千的產品得到了儲存,其餘則沒有。

要解決這個問題,有2個辦法。一是增加max_input_vars引數的值,二是修改magento程式碼。

1:修改Max_input_vars的值
Max_input_vars值又可以通過兩種方式來改變,修改htaccess或修改php.ini。
在magento根目錄的htaccess裡新增如下行,數值可以視情況改變:
php_value max_input_vars 2000

找到php.ini,找到max_input_vars = 1000,如果改行被註釋,就取消註釋,然後調整數值。為了使更 改生效,你可能需要重新啟動伺服器。

2:修改magento程式碼

改變max_input_vars值雖然快速且簡單。但是,如果你的產品和類別每天都在飛速增長著,這種重複 操作就顯得有點麻煩。為了避免這種情況,我們可以試著像下面來修改程式碼:

require_once 'Mage/Adminhtml/controllers/Catalog/CategoryController.php';
class Inchoo_Smile_Adminhtml_Catalog_CategoryController extends
Mage_Adminhtml_Catalog_CategoryController
{
public function saveAction()
{
...
 
if (isset($data['category_products']) && !$category->getProductsReadonly()) {
$products = array();
$exploded = explode('&', $data['category_products']);
 
foreach ($exploded as $row) {
$temp = array();
parse_str($row, $temp);
list($key, $value) = each($temp);
if(!empty($key)) {
$products[$key] = $value;
}
}
 
$category->setPostedProducts($products);
}
 
...
}
}


以上方法覆蓋了類控制器,但其實我們也可以使用一個更優雅的解決方案。還是在
Mage_Adminhtml_Catalog_CategoryController裡,在saveAction的時候,magento會出發一個event叫 catalog_category_prepare_save,通過這個事件就可以對資料進行修改,程式碼如下:

class Inchoo_Smile_Model_Observer
{
// event: catalog_category_prepare_save
public function assignCategoryProducts($observer)
{
$category = $observer->getCategory();
$request = $observer->getRequest();
 
$products = array();
$exploded = explode('&', $request->getParam('category_products'));
 
foreach ($exploded as $row) {
$temp = array();
parse_str($row, $temp);
list($key, $value) = each($temp);
 
if(!empty($key)) {
$products[$key] = $value;
}
}
 
$category->setPostedProducts($products);
}
 
}


以上程式碼可以放入任何一個你自己寫的module裡,然後再config里加上event即可,記著不要去修改 magento的核心程式碼。

來自於:jonas的magento部落格