Magento 2.2.1 Неможливо серіалізувати значення


12

Я оновив веб-сайт з 2.1.6 до 2.2.1 і зіткнувся з неможливою серіалізацією помилок значення у фронтеді та бекенді.

{"0":"Unable to serialize value.","1":"#0 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/Translate.php(494): Magento\\Framework\\Serialize\\Serializer\\Json->serialize(Array)\n
#1 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/Translate.php(190): Magento\\Framework\\Translate->_saveCache()\n
#2 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/App\/Area.php(244): Magento\\Framework\\Translate->loadData(NULL, false)\n
#3 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/App\/Area.php(215): Magento\\Framework\\App\\Area->_initTranslate()\n
#4 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/App\/Area.php(142): Magento\\Framework\\App\\Area->_loadPart('translate')\n
#5 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/View\/DesignLoader.php(55): Magento\\Framework\\App\\Area->load('translate')\n
#6 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/App\/Action\/Plugin\/Design.php(48): Magento\\Framework\\View\\DesignLoader->load()\n
#7 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/Interception\/Interceptor.php(121): Magento\\Framework\\App\\Action\\Plugin\\Design->beforeDispatch(Object(Magento\\Cms\\Controller\\Index\\Index\\Interceptor), Object(Magento\\Framework\\App\\Request\\Http))\n
#8 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/Interception\/Interceptor.php(153): Magento\\Cms\\Controller\\Index\\Index\\Interceptor->Magento\\Framework\\Interception\\{closure}(Object(Magento\\Framework\\App\\Request\\Http))\n
#9 \/var\/www\/vhosts\/demo.com\/eiselec\/generated\/code\/Magento\/Cms\/Controller\/Index\/Index\/Interceptor.php(39): Magento\\Cms\\Controller\\Index\\Index\\Interceptor->___callPlugins('dispatch', Array, Array)\n
#10 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/App\/FrontController.php(55): Magento\\Cms\\Controller\\Index\\Index\\Interceptor->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n
#11 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/Interception\/Interceptor.php(58): Magento\\Framework\\App\\FrontController->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n
#12 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/Interception\/Interceptor.php(138): Magento\\Framework\\App\\FrontController\\Interceptor->___callParent('dispatch', Array)\n
#13 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/module-store\/App\/FrontController\/Plugin\/RequestPreprocessor.php(94): Magento\\Framework\\App\\FrontController\\Interceptor->Magento\\Framework\\Interception\\{closure}(Object(Magento\\Framework\\App\\Request\\Http))\n
#14 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/Interception\/Interceptor.php(135): Magento\\Store\\App\\FrontController\\Plugin\\RequestPreprocessor->aroundDispatch(Object(Magento\\Framework\\App\\FrontController\\Interceptor), Object(Closure), Object(Magento\\Framework\\App\\Request\\Http))\n
#15 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/module-page-cache\/Model\/App\/FrontController\/BuiltinPlugin.php(73): Magento\\Framework\\App\\FrontController\\Interceptor->Magento\\Framework\\Interception\\{closure}(Object(Magento\\Framework\\App\\Request\\Http))\n
#16 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/Interception\/Interceptor.php(135): Magento\\PageCache\\Model\\App\\FrontController\\BuiltinPlugin->aroundDispatch(Object(Magento\\Framework\\App\\FrontController\\Interceptor), Object(Closure), Object(Magento\\Framework\\App\\Request\\Http))\n
#17 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/Interception\/Interceptor.php(153): Magento\\Framework\\App\\FrontController\\Interceptor->Magento\\Framework\\Interception\\{closure}(Object(Magento\\Framework\\App\\Request\\Http))\n
#18 \/var\/www\/vhosts\/demo.com\/eiselec\/generated\/code\/Magento\/Framework\/App\/FrontController\/Interceptor.php(26): Magento\\Framework\\App\\FrontController\\Interceptor->___callPlugins('dispatch', Array, NULL)\n
#19 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/App\/Http.php(135): Magento\\Framework\\App\\FrontController\\Interceptor->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n
#20 \/var\/www\/vhosts\/demo.com\/eiselec\/vendor\/magento\/framework\/App\/Bootstrap.php(256): Magento\\Framework\\App\\Http->launch()\n
#21 \/var\/www\/vhosts\/demo.com\/eiselec\/index.php(39): Magento\\Framework\\App\\Bootstrap->run(Object(Magento\\Framework\\App\\Http))\n
#22 {main}","url":"\/","script_name":"\/index.php"}

Дайте мені знати, як я можу це вирішити.

Дякую


Привіт, я говорю про значення серіалізації, а не несерійне значення.
Meetanshi

Ви спробували очистити кеш? не тільки кеш Magento, але і зовнішні кеші, якщо такі є.
MGento

так, я спробував.
Meetanshi

Чи можете ви спробувати з'ясувати, які дані ви намагаєтеся серіалізувати? Спробуйте перейти через сторонні модулі та з’ясувати, з якого модуля спрацьовує ця помилка. Можливо, вам може знадобитися переосмислити функцію серіалізації у файлі /vendor/magento/framework/Serialize/Serializer/Json.php
MGento

Чи трапляється ця помилка під час оновлення БД або після оновлення БД до версії 2.2.1?
drew7721

Відповіді:


4

у мене така ж поведінка з шаблоном. Я скопіював код помилки на свій серіалізатор, щоб отримати свою проблему.

Як тільки я перейду на de_DE і відновити свій статичний код через

sudo php bin/magento setup:static-content:deploy de_DE --jobs=0 -f

він викидає "Неправильно сформовані символи UTF-8, можливо, неправильно закодовані".

Тому я шукав файли, які я змінив у папці шаблонів (тобто код / ​​Mytheme / Bannerslider / i18n / de_DE.csv) і завантажував їх через WinSCP. Блокнот ++ показав "Ansii Encoding" - важко, для створення файлу перекладу я використовував "magento i18n: collection-phrases".

magento2dev # encguess app/code/MyTheme/Bannerslider/i18n/de_DE.csv

додаток / код / ​​MyTheme / Bannerslider / i18n / de_DE.csv US-ASCII

magento2dev # locale
LANG=de_DE.UTF-8
......

Тож я змінив файли вручну в Notepad ++, завантажив їх, розгорнув статичний вміст і скинув усі дозволи - en voila це працює.

Отже, помилка може бути у вашому файлі csv i18n.


10

Як я бачу, ця помилка походить від методу:

/**
 * Saving data cache
 *
 * @return $this
 */
protected function _saveCache()
{
    $this->_cache->save($this->getSerializer()->serialize($this->getData()), $this->getCacheId(true), [], false);
    return $this;
}

а серіалізатор, який не знайдено, походить від методу:

/**
 * Get serializer
 *
 * @return \Magento\Framework\Serialize\SerializerInterface
 * @deprecated 100.2.0
 */
private function getSerializer()
{
    if ($this->serializer === null) {
        $this->serializer = \Magento\Framework\App\ObjectManager::getInstance()
            ->get(Serialize\SerializerInterface::class);
    }
    return $this->serializer;
}

Перевагу для SerializerInterfaceдодано з 2.2.x версії Magento та оголошено у додатку / etc / di.xml :

<preference for="Magento\Framework\Serialize\SerializerInterface" type="Magento\Framework\Serialize\Serializer\Json" />

Тож я думаю, що ваш кеш-пам'ять старий або перевага до цього SerializerInterfaceне працює. Спробуйте налагодити цю проблему, зателефонувавши Magento\Framework\Serialize\SerializerInterface(використовуючи введення залежності) десь у коді та перевірте, який клас повертається ді:

public function __construct(\Magento\Framework\Serialize\SerializerInterface $serializer) 
{ 
    echo get_class($serializer);
}

Якщо він не повертає екземпляр Magento\Framework\Serialize\Serializer\Jsonкласу, що повернувся, спробуйте пошукати цей переписаний параметр у проекті та видалити його.

Якщо ви працюєте на віддаленому сервері - спочатку перевірте app/etc/di.xmlфайл на сервері безпосередньо.

Ще один спосіб ви можете тимчасово змінити основний Jsonсеріалізатор і перевірити, яка помилка повертається:

Відкрийте magento/framework/Serialize/Serializer/Json.phpта змініть цей метод із:

/**
 * {@inheritDoc}
 * @since 100.2.0
 */
public function serialize($data)
{
    $result = json_encode($data);
    if (false === $result) {
        throw new \InvalidArgumentException('Unable to serialize value.');
    }
    return $result;
}

до:

/**
 * {@inheritDoc}
 * @since 100.2.0
 */
public function serialize($data)
{
    $result = json_encode($data);
    if (false === $result) {
        switch (json_last_error()) {
            case JSON_ERROR_NONE:
                $error = ' - No errors';
                break;
            case JSON_ERROR_DEPTH:
                $error = ' - Maximum stack depth exceeded';
                break;
            case JSON_ERROR_STATE_MISMATCH:
                $error = ' - Underflow or the modes mismatch';
                break;
            case JSON_ERROR_CTRL_CHAR:
                $error = ' - Unexpected control character found';
                break;
            case JSON_ERROR_SYNTAX:
                $error = ' - Syntax error, malformed JSON';
                break;
            case JSON_ERROR_UTF8:
                $error = ' - Malformed UTF-8 characters, possibly incorrectly encoded';
                break;
            default:
                $error = ' - Unknown error';
                break;
        }
        throw new \InvalidArgumentException('Unable to serialize value. Error: ' . $error);
    }

    return $result;
}

Тоді ви зможете побачити після повідомлення про виключення помилку json. Можливо, ваші дані порушені. майте на увазі, що всі старі дані повинні бути несеріалізовані та серіалізовані за допомогою json у скриптах оновлення налаштувань під час оновлення magento.

PS: не забудьте відновити основні файли після завершення налагодження! Кращий спосіб - використовувати xDebug для цієї мети.


2
Ви повинні зробити цього помічника налагодження основним патчем - або запропонувати використовувати SAFE PHP github.com/thecodingmachine/safe
Alex

2

У моєму випадку причиною проблеми кодування UTF8 було небіотичне безпечне скорочення назв продуктів:

$productName = strlen($productName) > 60 ? substr($productName,0,60)."..." : 
      $productName;

Так а

012345678901234567890123456789012345678901234567890123456 Außengewinde 

став

012345678901234567890123456789012345678901234567890123456 Au�...

Це також було проблемою для наших. ixed це, замінивши "substr" на "mb_substr"
amesh

Працює як шарм !!!
Бхарат Севра

2

Будьте обережні з функцією substr. Він не підтримує UTF-8. І це може зламати FPC. Використовуйте mb_substr


1

У цьому ж питанні я працював із оновленням до 2.2.1. Я вважаю цей артикул дуже корисним http://devdocs.magento.com/guides/v2.2/ext-best-practices/tutorials/serialized-to-json-data-upgrade.html

Дані, що зберігаються в БД, більше не слід серіалізувати, вони тепер повинні зберігатися як об'єкт JSON.

Більшість модулів здійснюють оновлення даних, яке несеріалізує дані в БД і знову зберігає їх у форматі JSON. (До речі, це запустило досить багато часу)

Отже, якщо один із ваших модулів зберігає дані, що серіалізуються в БД, дані можуть більше не читатись Magento, вам потрібно буде зробити файл налаштування оновлення даних. Крім того, це може бути сторонній модуль, який потрібно оновити до версії, сумісної 2.2.

Якщо ви серіалізуєте несеріалізовані дані в будь-якому місці коду, можливо, вам доведеться це також змінити.

Я сподіваюся, що це дасть вам кращі уявлення про те, що викликає цю помилку.

Ура!


Обов’язково прочитайте Примітки до випуску для версії 2.2.1, партії змінилися, включаючи шлях до generationпапки. ;)
намалював7721

1

Я опинився точно в тій же ситуації. Після додавання коду вище я отримав "Неправильне формування символів UTF-8, можливо, неправильно закодований"

Я вважаю, що ви не використовуєте мову за замовчуванням. Спробуйте змінити мову на "за замовчуванням" en_US.

Meetanshi - Якою мовою ви користуєтесь в передній частині, а також створення статичного вмісту також не вдається?


Привіт @AP, я зіткнувся з тією ж помилкою, і я використовую мову de_DE.
Meetanshi

Спробуйте змінити на en_US. Таблиця core_config_data (загальна / локальна / код) для en_US
AP

та сама помилка після зміни на en_US.
Meetanshi

Мені вдалося його підняти, але в тупиковій спробі повернутися до fi_FI. Ви очистили кеш?
AP

так, я очистив кеш
Meetanshi

0

Для мене рішенням було замінити всі спеціальні символи типу "ä" у файлі csv перекладу на HTML-версії того самого символу, як цей:

&auml;

Тоді я очистив кеші і перезавантажив фронтенд.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.