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

Answers:


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下载了它们。Notepad ++显示了“ Ansii编码”-很难为翻译文件创建“ 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 ++中手动更改了文件,上传了文件,部署了静态内容并重置了所有权限-可以使用。

因此,该错误可能存在于您的i18n csv文件中。


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版本开始添加了的首选项,并在app / 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错误。可能是您的数据已损坏。请记住,在magento更新期间,应使用安装程序升级脚本中的json对所有旧数据进行反序列化和序列化。

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�...

这也是我们的问题。通过用“ mb_substr”替换“ 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格式再次存储。(顺便说一句,花了很长时间才能运行这个...)

因此,如果您的模块之一保存了在DB中序列化的数据,则Magento可能不再读取该数据,则需要制作一个数据升级安装文件。另外,它可能是第三方模块,需要更新到2.2+兼容版本。

如果确实要对代码中任何地方的非序列化数据进行序列化,则可能也必须更改它。

我希望这可以使您更好地了解导致此错误的原因。

干杯!


请务必阅读2.2.1的发行说明,其中的很多内容都已更改,包括generation文件夹的路径。;)
drew7721

1

我最终遇到了同样的情况。添加上面的代码后,我得到了“格式错误的UTF-8字符,可能编码错误”

我想您没有使用默认语言。尝试将语言更改为“默认” en_US。

Meetanshi-您在前端使用哪种语言,并且静态内容创建也失败了?


嗨,@ AP,我遇到同样的错误,并且我使用的是de_DE语言。
Meetanshi

尝试更改为en_US。表core_config_data(通用/语言环境/代码)到en_US
AP

更改为en_US后出现相同的错误。
Meetanshi

我设法将其启动,但尝试返回到fi_FI时却陷入僵局。您是否清除了缓存?
美联社

是的,我清除了缓存
Meetanshi

0

对我来说,解决方案是将翻译csv文件中的所有特殊字符(如“ä”)替换为相同字符的html版本,如下所示:

&auml;

然后,我清除了缓存并重新加载了前端。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.