Magento 2 composer.json エラー「値をアンシリアライズできません」 に関する詳細情報をお読みください。
Magento 2.2 バージョンのリリースにより、シリアル化に関する大きな変更 が導入されました。従来のシリアル化の代わりに JSON シリアル化が導入されています。データベース内には、シリアル化された値を使用しているいくつかのフィールドを含む多くのテーブルがあります。例えば、カタログルールテーブルです。Magento 2.2 で製品、注文、顧客を扱う際に、データのアンシリアライズを実行すると、「値をアンシリアライズできません」というエラーが表示されます。クライアントのプロジェクトで作業しているときに、カートに製品を追加しようとした際にも同じエラーが表示されました。このエラーは Magento 2.2.X バージョンでも既に発生しており、注文、製品、顧客データを扱う際に同じエラーが表示される可能性があります。この「値をアンシリアライズできません」の問題に対する解決策を見つけました。
これを解決するには、\vendor\magento\framework\Serialize\Serializer\json.php に移動し、以下の関数でファイルを置き換えてください。
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('値をアンシリアライズできません。'); } return $result; } function is_serialized($value, &$result = null) { // これはヒントですが if (!is_string($value)) { return false; } // シリアル化された false、true を返します。 unserialize() は無効な文字列の場合や、文字列がシリアル化された // false の場合に 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': // これは奇妙に見えますが、isset() よりも速いです $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; }
上記のコードを実装することで、古い値をアンシリアライズし、JSON を使用して再シリアライズすることができます。