Mặc dù một số câu trả lời có thể được tìm thấy trên các trang web khác, tôi nghĩ rằng nó là giá trị chia sẻ này trên StackOverflow ...
các nguồn gốc của vấn đề có thể được tìm thấy trong Mage_Adminhtml_Catalog_CategoryController
, nơi saveAction()
phương pháp lấy một chuỗi được đăng lớn (category_products
, được mã hóa như chuỗi truy vấn), được xử lý bằng hàm PHP parse_str()
:
if (isset($data['category_products']) && !$category->getProductsReadonly()) {
$products = array();
parse_str($data['category_products'], $products);
$category->setPostedProducts($products);
}
Than ôi! Từ phiên bản 5.3.9 của PHP, có một cài đặt cấu hình mới được gọi là max_input_vars
, giới hạn số biến đầu vào có thể được chấp nhận.
Giới hạn này chủ yếu được áp dụng cho $_GET
, $_POST
và $_COOKIE
superglobals, nhưng cũng được sử dụng nội bộ theo chức năng parse_str()
!
(Xem PHP manual)
Tùy thuộc vào cấu hình php.ini
của máy chủ của bạn, số lượng sản phẩm có liên quan đến một loại là do bị giới hạn bởi khung cảnh này ...
Một giải pháp là để tăng giá trị của max_input_vars
, trong php.ini
hoặc trong .htaccess
:
<IfModule mod_php5.c>
php_value max_input_vars 10000
</IfModule>
này thậm chí có thể được thực hiện một cách an toàn hơn bằng cách thay đổi thiết lập này chỉ dành cho trang quản trị (Thích nghi với mô hình LocationMatch để riêng phong cách URL back-office của bạn):
<LocationMatch "mymagentostore/(index\.php/)?admin/">
<IfModule mod_php5.c>
php_value max_input_vars 10000
</IfModule>
</LocationMatch>
(Source)
này chỉ giải quyết vấn đề cho đến khi một trong những hạng mục của bạn đạt đến số lượng tối đa mới của sản phẩm ...
Một giải pháp khác sẽ sửa mã của Magento theo thứ tự không phải để sử dụng hàm parse_str() tại thời điểm này.
Ví dụ, trong Mage_Adminhtml_Catalog_CategoryController
, saveAction()
phương pháp, thay thế:
parse_str($data['category_products'], $products);
với:
$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;
}
}
(Source)
Thật khó để quyết định giải pháp là tốt nhất, vì là người đầu tiên làm cho máy chủ của bạn dễ bị tấn công hơn (vì max_input_vars
có nghĩa là giảm thiểu khả năng tấn công từ chối dịch vụ sử dụng va chạm băm) và giải pháp thứ hai làm cho bạn sửa đổi một lớp cốt lõi Magento, có thể dẫn đến các vấn đề khác trong việc nâng cấp Magento trong tương lai ...
Hy vọng điều này là hữu ích, tôi đã gặp khó khăn một chút trước khi tìm hiểu lý do tại sao một số danh mục bị mất một số sản phẩm !
Bạn có thấy vấn đề với việc tăng điều này lên hơn 10.000 không? Chúng tôi có một số loại với hơn 31.000 sản phẩm ... –
Vâng, tôi đoán bạn có thể tăng giới hạn cho bất kỳ số nào (tuy nhiên, hiểu rằng điều này làm cho máy chủ của bạn dễ bị tấn công hơn đối với một số cuộc tấn công DoS). – programmeurweb
Đối với giải pháp thứ hai, không thể bạn chỉ cần ghi đè lên bộ điều khiển từ một mô-đun tùy chỉnh. Điều này sẽ làm cho nó nâng cấp an toàn vì tệp lõi vẫn chưa được sửa đổi. – russjman