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
источник
Привет, я говорю о значении сериализации, а не о несериализации значения.
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, возможно, неправильно закодированные».

Поэтому я посмотрел файлы, которые я изменил, в папке шаблонов (т.е. code / Mytheme / Bannerslider / i18n / de_DE.csv) и загрузил их через WinSCP. Notepad ++ показывал «Ansii Encoding» - я использовал «magento i18n: collect-phrases» для создания файла перевода.

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

app / code / MyTheme / Bannerslider / i18n / de_DE.csv US-ASCII

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

Поэтому я вручную изменил файлы в Notepad ++, загрузил их, развернул статический контент и сбросил все разрешения - и все работает.

Итак, ошибка может быть в вашем CSV-файле i18n.

Lord_Pinhead
источник
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было добавлено начиная с версии Magento версии 2.2.x и объявлено в приложении / etc / di.xml :

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

Так что я думаю, что ваш кеш старый или предпочтение SerializerInterfaceне работает. Попробуйте отладить эту проблему, вызвав Magento\Framework\Serialize\SerializerInterface(используя внедрение зависимостей) somwhere в коде, и проверьте, какой класс возвращен di:

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
Вы должны сделать этот помощник отладчика основным исправлением - или предложить, чтобы они использовали БЕЗОПАСНЫЙ PHP github.com/thecodingmachine/safe
Alex
2

В моем случае причиной проблемы кодировки UTF8 было не многобайтовое безопасное сокращение названий продуктов:

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

Так что

012345678901234567890123456789012345678901234567890123456 Außengewinde 

стал

012345678901234567890123456789012345678901234567890123456 Au�...
Alex
источник
Это было также проблемой для наших. исправил это, заменив «substr» на «mb_substr»
19
Работает как шарм !!!
Бхарат Севра
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+.

Если вы выполняете сериализацию на несериализованных данных в любом месте вашего кода, вам, возможно, придется это изменить.

Я надеюсь, что это поможет вам лучше понять причину этой ошибки.

Ура!

drew7721
источник
Обязательно прочтите Примечания к выпуску для 2.2.1, многое изменилось, включая путь к generationпапке. ;)
drew7721
1

Я оказался в той же ситуации. После добавления кода выше я получил «Неправильные символы UTF-8, возможно, неправильно закодированные»

Я полагаю, что вы не используете язык по умолчанию. Попробуйте изменить язык на «по умолчанию» en_US.

Meetanshi - Какой язык вы используете в front-end, и создание статического контента также не удается?

AP
источник
Привет @AP, я столкнулся с той же ошибкой, и я использую язык de_DE.
Meetanshi
Попробуйте изменить на en_US. Таблица core_config_data (general / locale / code) для en_US
AP
та же ошибка после изменения на en_US.
Meetanshi
Мне удалось получить его, но тупик при попытке вернуться к fi_FI. Вы очистили кеш?
AP
да, я очистил кеш
Meetanshi
0

Для меня решение состояло в том, чтобы заменить все специальные символы, такие как «ä» в CSV-файле перевода, на HTML-версии одного и того же символа, например:

&auml;

Затем я очистил кеши и перезагрузил интерфейс.

WebNinja
источник