解决magento批量assign产品到分类时最多只能save成功1000件的问

注 :文章中问题已在MagentoEE 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 changemax_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 extendsMage_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_savepublic 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博客

,我诚恳地希望能够获得你的原谅。只是你懂得的,对于有一些委屈,

解决magento批量assign产品到分类时最多只能save成功1000件的问

相关文章:

你感兴趣的文章:

标签云: