Magento 2.2: Tidak dapat meng-unserialize nilai?


33

Mengalami masalah di situs yang menjalankan Magento 2.2.0-rc3.0 / PHP 7.0.23

Masalah berikut ini terjadi dengan semua ekstensi pihak ke-3 diaktifkan atau dinonaktifkan.

Saat menambahkan item ke perbandingan dari kategori atau halaman produk atau mengirimkan ulasan dari halaman produk kami mendapatkan kesalahan berikut di browser:

1 exception(s):
Exception #0 (InvalidArgumentException): Unable to unserialize value.

Exception #0 (InvalidArgumentException): Unable to unserialize value.
#0 /home/___/public_html/app/code/Magento/Theme/Controller/Result/MessagePlugin.php(157): Magento\Framework\Serialize\Serializer\Json->unserialize('[{\\"type\\":\\"su...')
#1 /home/___/public_html/app/code/Magento/Theme/Controller/Result/MessagePlugin.php(135): Magento\Theme\Controller\Result\MessagePlugin->getCookiesMessages()
#2 /home/___/public_html/app/code/Magento/Theme/Controller/Result/MessagePlugin.php(84): Magento\Theme\Controller\Result\MessagePlugin->getMessages()
#3 /home/___/public_html/lib/internal/Magento/Framework/Interception/Interceptor.php(146): Magento\Theme\Controller\Result\MessagePlugin->afterRenderResult(Object(Magento\Framework\View\Result\Page\Interceptor), Object(Magento\Framework\View\Result\Page\Interceptor), Object(Magento\Framework\App\Response\Http\Interceptor))
#4 /home/___/public_html/lib/internal/Magento/Framework/Interception/Interceptor.php(153): Magento\Framework\View\Result\Page\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#5 /home/___/public_html/generated/code/Magento/Framework/View/Result/Page/Interceptor.php(26): Magento\Framework\View\Result\Page\Interceptor->___callPlugins('renderResult', Array, Array)
#6 /home/___/public_html/lib/internal/Magento/Framework/App/Http.php(139): Magento\Framework\View\Result\Page\Interceptor->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#7 /home/___/public_html/lib/internal/Magento/Framework/App/Bootstrap.php(256): Magento\Framework\App\Http->launch()
#8 /home/___/public_html/index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))
#9 {main}

Kesalahan tidak hilang kecuali Anda menghapus cookie, khususnya, cookie pesan-mage. masukkan deskripsi gambar di sini

Setiap bantuan dalam mengatasi kesalahan ini sangat kami hargai.


Bukankah itu bug inti? apakah ada masalah GitHub untuk ini?
Alex

ini akan memberi Anda ide scommerce-mage.com/blog/…
stevensagaar

Jawaban:


59

Saya bisa mengatasi masalah ini dengan Flushing Redis Cache saya dari CLI

redis-cli flushall

Saya harap ini membantu pengguna di masa depan.


2
Bagus sekali. Ini mungkin jawaban yang diterima.
Shawn Abramson

Tampaknya tidak selalu menjadi solusi. Dalam kasus saya saya bahkan tidak menggunakan Redis (belum)
Alex

Terima kasih. Saya memulai kembali pernis, berpikir itu akan menyiramnya, tetapi ini berhasil.
Ladle3000

itu bekerja untuk saya
Jared Chu

Ini membantu saya saat meningkatkan dari 2.2.9 ke 2.3.2. Saya mendapatkan kesalahan ketika saya menjalankan setup
Mohammed Joraid

30

Masalahnya ada di /vendor/magento/framework/Serialize/Serializer/Json.php ada fungsi unserialize ($ string) yang memberi Anda kesalahan sintaks jika string serial (bukan json tapi serialisasi php).

Ada solusi - Anda dapat memeriksa apakah string serial (vs json-encoded) dan kemudian menggunakan serialize ($ string). Ubah unserialize ke:

public function unserialize($string)
{
    if($this->is_serialized($string))
    {
        $string = $this->serialize($string);
    }
    $result = json_decode($string, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
         throw new \InvalidArgumentException('Unable to unserialize value.');

    }
    return $result;
}

dan tambahkan fungsi untuk memeriksa apakah string diserialisasi:

function is_serialized($value, &$result = null)
{
    // Bit of a give away this one
    if (!is_string($value))
    {
        return false;
    }
    // Serialized false, return true. unserialize() returns false on an
    // invalid string or it could return false if the string is serialized
    // false, eliminate that possibility.
    if ($value === 'b:0;')
    {
        $result = false;
        return true;
    }
    $length = strlen($value);
    $end    = '';
    switch ($value[0])
    {
        case 's':
            if ($value[$length - 2] !== '"')
            {
                return false;
            }
        case 'b':
        case 'i':
        case 'd':
            // This looks odd but it is quicker than isset()ing
            $end .= ';';
        case 'a':
        case 'O':
            $end .= '}';
            if ($value[1] !== ':')
            {
                return false;
            }
            switch ($value[2])
            {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                    break;
                default:
                    return false;
            }
        case 'N':
            $end .= ';';
            if ($value[$length - 1] !== $end[0])
            {
                return false;
            }
            break;
        default:
            return false;
    }
    if (($result = @unserialize($value)) === false)
    {
        $result = null;
        return false;
    }
    return true;
}

Setelah menyimpan fe. kategori tanpa masalah, Anda dapat mengembalikan kelas ke default dan tidak akan ada masalah seperti itu di masa depan.


1
Ini bekerja 100% baik untuk saya. Terima kasih banyak!
mapaladiya

2
itu tidak berfungsi ... :-(
Arfan Mirza

Periksa apa yang terjadi jika nilai a: 0: {} dilewatkan. Pergi baris demi baris. Apa yang terjadi jika hasil unserialize diteruskan ke metode yang diketik kuat yang mengharapkan array? Anda mungkin ingin mengubah jawaban Anda.
vitoriodachef

20

Jangan mengedit file inti untuk solusi. Mengganti cara berikut. Cukup masukkan baris berikut di di.xml di dalam direktori dll

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

Dan di dalam Namespace \ ModuleName \ Serialize \ Serializer Directory: file Json.php

<?php
namespace Namespace\ModuleName\Serialize\Serializer;



class Json extends \Magento\Framework\Serialize\Serializer\Json
{


    /**
     * {@inheritDoc}
     * @since 100.2.0
     */
    public function unserialize($string)
    {
      if($this->is_serialized($string))
        {
            $string = $this->serialize($string);
        }
        $result = json_decode($string, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
             throw new \InvalidArgumentException('Unable to unserialize value.');

        }
        return $result;
    }


    function is_serialized($value, &$result = null)
    {
    // Bit of a give away this one
        if (!is_string($value))
        {
            return false;
        }
        // Serialized false, return true. unserialize() returns false on an
        // invalid string or it could return false if the string is serialized
        // false, eliminate that possibility.
        if ($value === 'b:0;')
        {
            $result = false;
            return true;
        }
        $length = strlen($value);
        $end    = '';
        switch ($value[0])
        {
            case 's':
                if ($value[$length - 2] !== '"')
                {
                    return false;
                }
            case 'b':
            case 'i':
            case 'd':
                // This looks odd but it is quicker than isset()ing
                $end .= ';';
            case 'a':
            case 'O':
                $end .= '}';
                if ($value[1] !== ':')
                {
                    return false;
                }
                switch ($value[2])
                {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                        break;
                    default:
                        return false;
                }
            case 'N':
                $end .= ';';
                if ($value[$length - 1] !== $end[0])
                {
                    return false;
                }
                break;
            default:
                return false;
        }
        if (($result = @unserialize($value)) === false)
        {
            $result = null;
            return false;
        }
        return true;
    }
}

Bekerja dengan sempurna


2
Implementasinya cacat. Apa yang terjadi jika nilai a: 0: {} diteruskan ke Json: metode unserialize? Apakah itu perilaku yang diinginkan? Apa poin dari variabel hasil dalam metode is_serialized? Itu tidak dikembalikan dan tidak memiliki dampak terhadap apa pun karena pada pemanggilan metode tidak ada variabel yang dilewatkan sebagai argumen kedua.
vitoriodachef

Ini harus menjadi solusi yang diterima, dan jauh lebih baik daripada posting di atas untuk mengedit file langsung di vendor. Kemungkinan besar, Anda harus menjalankan tugas peningkatan pengaturan secara lokal dan kemudian lagi pada pementasan / produksi, sehingga harus bertahan lingkungan dan vendor / direktori adalah artefak yang dibuat pada waktu membangun.
Mark Shust

@vitoriodachef Saya menghadapi kasus persis yang telah Anda sebutkan. Apakah Anda menemukan solusi?
Knight017

Saya telah menggunakan fungsi berikut untuk memutuskan fungsi privat isSerialized ($ value) {return (boolean) preg_match ('/ ^ ((s | i | d | b | a | O | C): | N;) /', $ value ); }
Knight017

Tidak bekerja Saya harus mengubah semua entri dalam DB secara manual dari a:0:{}menjadi[]
localhost

16

Dalam kasus saya, saya menambal sebagai berikut untuk membatalkan serial string: File: / vendor/magento/framework/Serialize/Serializer/Json.php

Menemukan:

public function unserialize($string)
{
    $result = json_decode($string, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new \InvalidArgumentException('Unable to unserialize value.');
    }
    return $result;
}

ganti dengan:

public function unserialize($string)
{
    $result = json_decode($string, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        if(false !== @unserialize($string)){
            return unserialize($string);
        }
        throw new \InvalidArgumentException('Unable to unserialize value.');
    }
    return $result;
}

Saya sudah mencoba ini tetapi tidak berfungsi seperti yang diharapkan. Adakah yang mencoba ini dan jika berhasil, tolong bantu saya
Siva

Masalah apa yang Anda hadapi?
MageLearner

Masalahnya diperbaiki. Terima kasih untuk bertanya!
Siwa

1
Grt ... Terima kasih !!!
MageLearner

1
Terima kasih @MageLearner, Ini juga berfungsi di 2.3.1 setelah memigrasikan data dari magento 1 ke magento 2
Pradeep Thakur

5

Setelah memerah Redis masalah telah diurutkan. Terima kasih Craig untuk solusinya.

Saya menggunakan port 6379 untuk cache, jadi saya menjalankan perintah:

redis-cli -p 6379 flushall

4

Ini sebagian besar terkait dengan cache Redis, jadi cobalah untuk menghapus ini dengan perintah sederhana di SSH Anda

redis-cli flushall


3

Itu ternyata menjadi masalah izin, di mana magento sedang mengatur izin untuk file yang dihasilkan yang dibatasi pada server ini.

Dipecahkan dengan membuat file magento_umask di direktori root dengan umask yang sesuai untuk server.

Lihat http://devdocs.magento.com/guides/v2.2/install-gde/install/post-install-umask.html untuk detail tambahan.


Halo, saya menghadapi masalah terkait seperti ini. Bisakah Anda melihat ini ?
Aditya Shah

@Chunk semua dir saya adalah 755, dan file 644, apa umask yang sesuai untuk ditetapkan? tia
Kris Wen

2

Jawaban pengirim di atas bekerja untuk saya walaupun saya harus menggunakan kode yang berbeda di blok.

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

function is_serialized($value, &$result = null)
{
    // Bit of a give away this one
    if (!is_string($value))
    {
        return false;
    }
    // Serialized false, return true. unserialize() returns false on an
    // invalid string or it could return false if the string is serialized
    // false, eliminate that possibility.
    if ($value === 'b:0;')
    {
        $result = false;
        return true;
    }
    $length = strlen($value);
    $end    = '';
    switch ($value[0])
    {
        case 's':
            if ($value[$length - 2] !== '"')
            {
                return false;
            }
        case 'b':
        case 'i':
        case 'd':
            // This looks odd but it is quicker than isset()ing
            $end .= ';';
        case 'a':
        case 'O':
            $end .= '}';
            if ($value[1] !== ':')
            {
                return false;
            }
            switch ($value[2])
            {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                    break;
                default:
                    return false;
            }
        case 'N':
            $end .= ';';
            if ($value[$length - 1] !== $end[0])
            {
                return false;
            }
            break;
        default:
            return false;
    }
    if (($result = @unserialize($value)) === false)
    {
        $result = null;
        return false;
    }
    return true;
}

/**
 * {@inheritDoc}
 */
public function unserialize($string)
{
    if($this->is_serialized($string))
        {
        $result = $this->serialize($string);
        }
    $result = json_decode($string, true);

    return $result;
}

1

Direktori ROOT 1. public_html/vendor/magento/framework/Serialize/Serializer/Json.php

Unduh JSON.php https://gist.github.com/manojind/9f18bbecaeb3e2bbfb056a634ade62a2

2. Cukup ganti fungsi di bawah ini (batalkan register) dan tambahkan fungsi baru ATAU unduh saja file yang terlampir dan ganti dengan default

public function unserialize($string)
{
    if($this->is_serialized($string))
    {
        $string = $this->serialize($string);
    }
    $result = json_decode($string, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
         throw new \InvalidArgumentException('Unable to unserialize value.');

    }
    return $result;
}

3. Tambahkan fungsi baru:

function is_serialized($value, &$result = null)
{

    if (!is_string($value))
    {
        return false;
    }

    if ($value === 'b:0;')
    {
        $result = false;
        return true;
    }
    $length = strlen($value);
    $end    = '';
    switch ($value[0])
    {
        case 's':
            if ($value[$length - 2] !== '"')
            {
                return false;
            }
        case 'b':
        case 'i':
        case 'd':
                       $end .= ';';
        case 'a':
        case 'O':
            $end .= '}';
            if ($value[1] !== ':')
            {
                return false;
            }
            switch ($value[2])
            {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                    break;
                default:
                    return false;
            }
        case 'N':
            $end .= ';';
            if ($value[$length - 1] !== $end[0])
            {
                return false;
            }
            break;
        default:
            return false;
    }
    if (($result = @unserialize($value)) === false)
    {
        $result = null;
        return false;
    }
    return true;
} 

Masalah saya belum diperbaiki .. Tolong bantu saya
Muhammad Ahmed

1

Saya pribadi menemukan bahwa masalah ini muncul karena kepala menjalankan perintah:

php bin/magento setup:upgrade

Setelah migrasi. Saya menemukan bahwa saya kehilangan kunci hash " crypt " di src/app/etc/env.php:

<?php
return [
    'backend' => [
        'frontName' => 'admin'
    ],
    'crypt' => [
        'key' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    ],

    ...

Pastikan ini tidak kosong dan sebaiknya cocok dengan lingkungan proyek Anda yang lain!


Saya meninggalkan kunci crypt kosong selama instalasi mengharapkan yang baru akan dihasilkan, yang jelas tidak terjadi.
Shapeshifter

0

Saya mendapatkan kesalahan di halaman CMS di ujung depan.

Itu adalah kode widget Magento di Konten Halaman CMS yang menyebabkan masalah (yang saya salin dari sumber lain). Saya menghapus kode widget dan memasukkan widget yang sama menggunakan tombol Sisipkan Widget di layar edit Halaman CMS dan berhasil.

Proses di atas memformat kode widget secara berbeda dan membuat kesalahan hilang.


0

Saya menemukan bahwa seluruh data serial tidak dapat masuk ke dalam kolom tabel database MySQL dengan TEXTtipe data.
Saya baru saja menemukan nilai kolom flag_datadari system_config_snapshotgaris terpangkas.

Saya harus mengubahnya ke MEDIUMTEXTuntuk kolom ini flag.flag_data.


0

Kesalahan yang sama. Ketika mencoba memperbarui basis data (ver 2.2.6) dengan kode baru (ver 2.3.2).

Untuk memperbaiki - menjalankan

composer update

0

Ini bukan cara terbaik untuk menjalankan sql secara langsung tetapi saya melakukan itu untuk menghemat waktu saya. Jalankan saja pertanyaan ini

ALTER TABLE flag MODIFY flag_data LONGTEXT;
UPDATE flag SET flag_data = '{"system":"","scopes":"","themes":""}' WHERE flag_code = 'config_hash';
UPDATE flag SET flag_data = '{}' WHERE flag_code = 'system_config_snapshot';

0

Jika Anda menggunakan 2.3.0 atau lebih tinggi, Anda akan ingin menggunakan solusi yang disediakan oleh MageLearner. Cara lama dengan pernyataan kasus sudah usang. Jika Anda tidak menggunakan solusi MageLearner di 2.3.0 atau lebih tinggi; Anda akan menghadapi semua jenis masalah dengan melihat data pesanan dan produk yang dapat dikonfigurasi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.