虽然可以在其他网站上找到一些答案,但我认为值得在StackOverflow上分享这个...
问题的根源可以在 中找到,其中该方法检索一个大的POSTed字符串(编码为查询字符串),该字符串由PHP函数处理:Mage_Adminhtml_Catalog_CategoryController
saveAction()
category_products
parse_str()
if (isset($data['category_products']) && !$category->getProductsReadonly()) {
$products = array();
parse_str($data['category_products'], $products);
$category->setPostedProducts($products);
}
唉!从 PHP 的 5.3.9 版开始,有一个名为 的新配置设置,它限制了可以接受的输入变量的数量。
此限制主要应用于 和 超全局,但也由函数内部使用!
(参见 PHP 手册max_input_vars
$_GET
$_POST
$_COOKIE
parse_str()
)
因此,根据主机的配置,链接到某个类别的产品数量受此设置的限制...php.ini
一种解决方案是增加 的值,在 或 在 中:max_input_vars
php.ini
.htaccess
<IfModule mod_php5.c>
php_value max_input_vars 10000
</IfModule>
通过仅更改管理页面的此设置,甚至可以更安全地完成此操作(将LocationMatch模式调整为您自己的后台URL样式):
<LocationMatch "mymagentostore/(index\.php/)?admin/">
<IfModule mod_php5.c>
php_value max_input_vars 10000
</IfModule>
</LocationMatch>
(源)
这只能解决问题,直到您的一个类别达到新的最大产品数量...
另一种解决方案是修复Magento的代码,以便此时不使用parse_str()函数。
例如,在 中,方法中,替换:Mage_Adminhtml_Catalog_CategoryController
saveAction()
parse_str($data['category_products'], $products);
跟:
$cat_products_split = explode('&', $data['category_products']);
foreach($cat_products_split as $row) {
$arr = array();
parse_str($row, $arr); //This will always work
list($k, $v) = each($arr);
if (!empty($k) && !empty($v)) {
$products[$k] = $v;
}
}
(源)
很难确定哪种解决方案是最好的,因为第一个解决方案使您的服务器更容易受到攻击(因为该解决方案旨在减轻使用哈希冲突的拒绝服务攻击的可能性),而第二个解决方案使您修改Magento核心类,这可能导致将来Magento升级中的进一步问题...max_input_vars
希望这无论如何都是有用的,在我找出为什么某些类别不断失去某些产品之前,我挣扎了一段时间!