解决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博客

时间: 2024-10-09 05:28:55

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

magento -- 如何在magento中进行产品的批量上传

花费了好多时间,阅读了magento官方论坛上几乎所有的批量上传产品的相关帖子,分析了大量相关magento代码,终于可以完全实现指产品批量上传的功能,免除网速慢,在页面之间跳来跳去,以及重复输入数据的烦恼,你只需要在excel中编辑数据就可以轻松实现产品批量上传到magento站点. 碰到的常见问题(统统搞定,哈哈): 多图上传 上传后magento前台无法查看 上传后前台看不了图片 上传后前台只能看到部分图片 上传后前台的图片有重复 不能上传custom option(可以支持基于optio

解决magento添加产品在前台不显示问题

有时候我们在magento系统添加产品,前台不显示,最模板分析可能 以下几个原因: 1 添加新品要重新index一下,magento是静态的.html页面,不reindex不出来的.在System→Index Management里面,全选后点Reindex.2 产品有很多属性影响是否前台显示: qty:数量为0前台不显示. is_in_stock:no的话前台不显示. status:disable的话前台不显示 visibility:none的话前台不显示. 3 有的时候,如果你操作不当,ca

解决远程桌面连接Windows Server 2003时提示“终端服务器超出了最大允许连接数”的问题

声明 作者:昨夜星辰 博客:http://yestreenstars.blog.51cto.com/ 本文由本人创作,如需转载,请注明出处,谢谢合作! 目的 解决远程桌面连接Windows Server 2003时提示"终端服务器超出了最大允许连接数"的问题. 环境 OS:Windows Server 2003 配置 1.在开始之前先确认你的服务器能连接互联网: 2.打开"Windows 组件向导"(开始 -> 控制面板 -> 添加或删除程序 ->

PHP在无限分类时注意的一些问题(不保证代码完全正确哦)

转自:PHP在无限分类时注意的一些问题(http://lxiaoke.cn) (注意:代码使用的是原生PHP,旨在提供解决思路)1 无限分类的查找(获取所有节点) 代码: /** * 无限分类查询,默认 pid 为 0 * @param $pid * @return array $res */ protected function selectTree($pid = 0) { $res = []; $sql = "SELECT * FROM " . $this->tbname .

解决CSS3多列样式column-width布局时内容被截断、错乱

一.问题 使用CSS3的column-width: auto | <length>属性时,出现排列的内容被截断,出现错位的现象. 二.原因 需要为图片容器设置高度,不然会崩掉. 三.解决方法 给需要分列的容器加上height:100%;overflow: auto;. 解决CSS3多列样式column-width布局时内容被截断.错乱

[已解决]C#批量高效率导入大数据到数据库[百万级以上]

将几百万条数据导入到数据库中,怎么样高效率的导入?下面我就介绍一个高效率的方法:1.将数据库文件(DB.csv)导入到DataTable中: /// <summary> /// 将CSV文件的数据读取到DataTable中 /// </summary> /// <param name="fileName">CSV文件路径</param> /// <returns>返回读取了CSV数据的DataTable</returns

SpringMVC3.2 解决PO返回前台转成JSON时数据Long精度丢失问题

SpringMVC3.2  解决PO返回前台转成JSON时数据Long精度丢失问题 方案 1.自定义一个杰克逊的json转换类 public class LongToStringAdapter extends ObjectMapper { private static final long serialVersionUID = 4402127997078513582L; public LongToStringAdapter() { super(); SimpleModule simpleModu

产品在焊接时出现异常,尤其是尺寸较大的QFP芯片,焊接后出现虚焊、冷焊、假焊等问题?

1 不良描述 客户采用我们提供的SMT设备后,部分产品在焊接时出现异常,尤其是尺寸较大的QFP芯片,焊接后出现虚焊.冷焊.假焊等不良.应客户要求对这一批不良产品以及生产条件进行分析,以便找到改善的依据. 对不良样品进行外观检查,发现多处排阻出现严重偏移导致断路(图3):部分样品上QFP芯片偏移严重,导致焊接不良(图4):部分样品的QFP芯片出现冷焊现象(图5):部分样品出现贴片问题,芯片底部有异物(图6):部分样品的焊盘不沾锡(图7):未焊接的PCB焊盘也存在一定程度的破损(图8) 2   分析

解决Oracle 11g在用EXP导出时,空表不能导出

一.问题原因:     11G中有个新特性,当表无数据时,不分配segment,以节省空间     1.insert一行,再rollback就产生segment了. 该方法是在在空表中插入数据,再删除,则产生segment.导出时则可导出空表. 2.设置deferred_segment_creation 参数 show parameter deferred_segment_creation NAME                                 TYPE        VALU