虽然可以在其他网站上找到一些答案,但我认为值得在 StackOverflow 上分享这个......
问题的根源可以在 中找到Mage_Adminhtml_Catalog_CategoryController
,该saveAction()
方法检索一个大的 POST 字符串(category_products
编码为查询字符串),该字符串由 PHP 函数处理parse_str()
:
if (isset($data['category_products']) && !$category->getProductsReadonly()) {
$products = array();
parse_str($data['category_products'], $products);
$category->setPostedProducts($products);
}
唉! 从 PHP 5.3.9 版本开始,有一个名为 的新配置设置max_input_vars
,它限制了可以接受的输入变量的数量。
这个限制主要应用于$_GET
,$_POST
和$_COOKIE
超全局变量,但也被parse_str()
函数内部使用!
(见PHP 手册)
根据php.ini
您主机的配置,链接到一个类别的产品数量因此受到此设置的限制...
一种解决方案是增加max_input_vars
、 inphp.ini
或 in的值.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;
}
}
(来源)
很难确定哪种解决方案是最好的,因为第一个解决方案使您的服务器更容易受到攻击(因为max_input_vars
它旨在减轻使用哈希冲突的拒绝服务攻击的可能性),而第二个解决方案使您修改 Magento核心类,这可能会在未来的 Magento 升级中导致进一步的问题......
无论如何,希望这很有用,我挣扎了一段时间才找出为什么某些类别不断失去一些产品!