Magento 2.2.1 Impossible de sérialiser la valeur

12

J'ai mis à niveau le site Web de 2.1.6 à 2.2.1 et je ne peux pas sérialiser l'erreur de valeur dans le frontend et le backend.

{"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"}

Faites-moi savoir comment puis-je le résoudre.

Merci

Meetanshi
la source
Salut, je parle de valeur de sérialisation et non de désériérisation.
Meetanshi
Avez-vous essayé de vider le cache? non seulement le cache Magento, mais également les caches externes.
MGento
oui, j'ai essayé.
Meetanshi
Pouvez-vous essayer de savoir quelles données vous essayez de sérialiser? Essayez de parcourir vos modules tiers et découvrez à partir de quel module cette erreur est déclenchée. Vous devrez probablement remplacer la fonction de sérialisation, dans le fichier /vendor/magento/framework/Serialize/Serializer/Json.php
MGento
Cette erreur se produit-elle pendant la mise à jour de la base de données ou après avoir mis à jour la base de données vers la version 2.2.1?
drew7721

Réponses:

4

j'ai le même comportement avec un modèle. J'ai copié le code de l'erreur sur mon sérialiseur pour obtenir mon problème.

Dès que je passe à de_DE et régénère mon code statique via

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

il lance "des caractères UTF-8 mal formés, éventuellement mal encodés".

J'ai donc recherché les fichiers que j'ai modifiés dans le dossier du modèle (par exemple code / Mytheme / Bannerslider / i18n / de_DE.csv) et les ai téléchargés via WinSCP. Notepad ++ montrait "Ansii Encoding" - difficile, j'ai utilisé "magento i18n: collect-phrases" pour le fichier de traduction à créer.

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

J'ai donc changé les fichiers manuellement dans Notepad ++, les ai téléchargés, déployé le contenu statique et réinitialisé toutes les autorisations - en voila cela fonctionne.

Ainsi, le bogue pourrait être dans votre fichier csv i18n.

Lord_Pinhead
la source
10

Comme je peux le voir, cette erreur provient de la méthode:

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

et le sérialiseur non trouvé provient de la méthode:

/**
 * 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;
}

La préférence pour le a SerializerInterfaceété ajoutée depuis la version 2.2.x de Magento, et déclarée dans l' application / etc / di.xml :

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

Je pense donc que votre cache est ancien ou que la préférence pour le SerializerInterfacene fonctionne pas. Essayez de déboguer ce problème en appelant le Magento\Framework\Serialize\SerializerInterface(à l'aide de l'injection de dépendance) quelque part dans le code, et vérifiez quelle classe retournée par di:

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

Si elle ne retourne pas une instance de la Magento\Framework\Serialize\Serializer\Jsonclasse retournée - essayez de rechercher cette préférence écrasée dans le projet et supprimez-la.

Si vous travaillez sur le serveur distant - vérifiez d'abord le app/etc/di.xmlfichier directement sur le serveur.

Vous pouvez également modifier temporairement le Jsonsérialiseur principal et vérifier l'erreur renvoyée:

Ouvrez le magento/framework/Serialize/Serializer/Json.phpet modifiez cette méthode à partir de:

/**
 * {@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;
}

Ensuite, vous pouvez voir après le message d'exception une erreur json. Peut-être que vos données sont cassées. gardez à l'esprit que toutes les anciennes données doivent être non sérialisées et sérialisées à l'aide de json dans les scripts de mise à niveau de l'installation lors de la mise à jour de magento.

PS: n'oubliez pas de restaurer les fichiers core une fois le débogage terminé! La meilleure façon est d'utiliser xDebug à cet effet.

Siarhey Uchukhlebau
la source
2
Vous devez faire ce débogueur aide d' un patch de base - ou suggérer qu'ils utilisent SÛR PHP github.com/thecodingmachine/safe
Alex
2

Dans mon cas, la cause d'un problème de codage UTF8 était le raccourcissement sûr non multioctet des noms de produit:

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

Donc un

012345678901234567890123456789012345678901234567890123456 Außengewinde 

est devenu

012345678901234567890123456789012345678901234567890123456 Au�...
Alex
la source
C'était aussi le problème pour notre. Je l'ai corrigé en remplaçant "substr" par "mb_substr"
amesh
Fonctionne comme un charme !!!
Bharat Sevra
2

Soyez prudent avec la fonction substr. Il ne prend pas en charge UTF-8. Et cela peut briser le FPC. Utilisez mb_substr

Arni
la source
1

J'ai rencontré le même problème avec la mise à niveau vers 2.2.1. J'ai trouvé cet article très utile http://devdocs.magento.com/guides/v2.2/ext-best-practices/tutorials/serialized-to-json-data-upgrade.html

Les données stockées dans la base de données ne doivent plus être sérialisées, elles doivent maintenant être enregistrées en tant qu'objet JSON.

La plupart des modules effectuent une mise à jour des données qui désérialise les données dans la base de données et les stocke à nouveau sous un format JSON. (BTW Il a fallu un certain temps pour exécuter cela ...)

Par conséquent, si l'un de vos modules enregistre des données qui sont sérialisées dans la base de données et que ces données pourraient ne plus être lisibles par Magento, vous devrez créer un fichier d'installation de mise à niveau des données. Il peut également s'agir d'un module tiers qui doit être mis à jour vers une version compatible 2.2+.

Si vous sérialisez sur des données non sérialisées n'importe où dans votre code, vous devrez peut-être également changer cela.

J'espère que cela vous donne une meilleure idée de la cause de cette erreur.

À votre santé!

drew7721
la source
Assurez-vous de lire les notes de publication de 2.2.1, beaucoup a changé, y compris le chemin d'accès au generationdossier. ;)
drew7721
1

Je me suis retrouvé exactement à la même situation. Après avoir ajouté le code ci-dessus, j'ai "des caractères UTF-8 mal formés, éventuellement incorrectement encodés"

Je suppose que vous n'utilisez pas la langue par défaut. Essayez de changer la langue en "par défaut" en_US.

Meetanshi - Quelle langue vous utilisez en front-end et la création de contenu statique échoue-t-elle également?

AP
la source
Salut @AP, je fais face à la même erreur et j'utilise le langage de_DE.
Meetanshi
Essayez de passer à en_US. Table core_config_data (general / locale / code) à en_US
AP
même erreur après avoir changé en en_US.
Meetanshi
J'ai réussi à le relever, mais sans issue en essayant de revenir à fi_FI. Avez-vous vidé le cache?
AP
oui, j'ai vidé le cache
Meetanshi
0

Pour moi, la solution était de remplacer tous les caractères spéciaux comme "ä" dans le fichier de traduction csv par des versions html du même caractère comme ceci:

&auml;

Ensuite, j'ai effacé les caches et rechargé le frontend.

Webninja
la source