開発者は、PHPのシリアル化および非正規化機能を使用する場合、「非透明化できない」エラーに遭遇する可能性があります。通常、このエラーは、PHPが文字列をオブジェクトまたは配列に正常にゆるくすることができないことを示しています。この記事では、いくつかの一般的な理由とこの問題を解決する方法について説明します。
Serialize関数は、PHPデータ構造(オブジェクトや配列など)を文字列に変換できますが、 Unserializeは文字列を元のデータ構造に変換します。ただし、場合によっては、 unserializeを呼び出す場合、次のようなエラーメッセージに遭遇する可能性があります。
Warning: unserialize(): Error at offset 0 of 2 bytes in /path/to/script.php on line 20
Cannot unserialize
このエラーは通常、次の理由により発生します。
最も一般的な理由の1つは、シリアル化されたデータが改ざんまたは破損していることです。これは、URLまたはデータベースを介してデータを保存する場合など、転送中に発生する可能性があります。シリアル化されたデータが誤って変更されている場合、 Unserializeは元の構造を復元できません。
解決:
シリアル化されたデータが、ストレージと送信中に破損したり変更されたりしないことを確認してください。 URLパラメーターを使用してシリアル化データを渡す場合、データの変更を引き起こす特殊文字( & 、 = 、?など)があるかどうかを確認します。
URLでシリアル化されたデータを渡す場合は、 Urlencodeを使用してシリアル化された文字列をエンコードしてください。受信機は、特別な文字干渉を避けるためにUrldeCodeを使用してデコードします。
// 転送前に使用します urlencode コーディング
$serialized_data = urlencode(serialize($data));
// 受け取った後にデコードして脱介入します
$data = unserialize(urldecode($serialized_data));
シリアル化されたオブジェクトにクラスが含まれており、脱派化中にクラスが見つからない場合、PHPは「非立体化できない」エラーをスローします。たとえば、クラスのファイルが正しく含まれていないか、クラスの名前が変更されていない可能性があります。
解決:
特にオブジェクトを使用する場合は、必要なすべてのクラスが正しくロードされていることを確認してください。クラスファイルは、 spl_autoload_registerを使用して自動的にロードできます。
クラスの名前が変更または削除された場合は、シリアル化されたデータのバージョンと構造を確認して、クラス名の一貫性を維持していることを確認してください。
// クラスを自動的にロードします
spl_autoload_register(function ($class) {
include 'path/to/classes/' . $class . '.php';
});
シリアル化されたデータが異なるPHPバージョン間で転送される場合、一部のPHPバージョン間に非互換性がある場合があります。特に、PHP 7とPHP 8は、オブジェクトのシリアル化をいくつかの変更を加えたため、脱3が失敗する可能性があります。
解決:
PHPバージョンがすべてのランタイム環境で一貫していることを確認するか、脱出前にデータの適切な処理を検討してください(たとえば、互換性のある形式に変換)。
PHPバージョンを制御できない場合は、シリアル化の代わりにJSON形式を使用してみてください。
// 使用 JSON 代替 serialize
$json_data = json_encode($data);
// 使用 json_decode 代替 unserialize
$data = json_decode($json_data, true);
異なる文字エンコードシステム間でシリアル化されたデータを渡すと、一貫性のない文字セットに遭遇する可能性があります。これにより、通常、データを正しくデコードできなくなります。
解決:
特にデータを転送する場合、データの文字エンコードが一貫していることを確認してください。統合された文字セット(UTF-8など)は、エンコードの問題を避けるためにデータを保存するときに使用できます。
// 设置字符コーディング为 UTF-8
mb_internal_encoding("UTF-8");
シリアル化されたオブジェクトにPHPリソースタイプ(データベース接続、ファイルハンドルなど)が含まれている場合、これらのリソースは脱出中に復元できないため、エラーが発生する可能性があります。
解決:
オブジェクトをシリアル化する前に、オブジェクトからリソースメンバーを削除するか、 __スリープおよび__ウェイクアップメソッドを実装して、リソースのリリースとリカバリを処理してください。
class MyClass {
private $file;
public function __sleep() {
// シリアル化前にリソースを削除します
unset($this->file);
return ['file']; // シリアル化する必要がある属性を返します
}
public function __wakeup() {
// 降下後にリソースを再開します
$this->file = fopen('path/to/file', 'r');
}
}
「非正規化」エラーに遭遇した場合、いくつかのデバッグテクニックを使用して問題をトラブルシューティングできます。
シリアル化されたデータの整合性を確認します。シリアル化された文字列を出力して、完全に見えることを確認してください。
エラーレポートの有効化: ERROR_REPORTING(E_ALL)およびINI_SET( 'Display_Errors'、1)を使用して、詳細なエラーレポートを有効にして可能なプロンプトを表示します。
var_dumpでデータを確認してください:脱出前に、 var_dumpを使用して、データの形式とコンテンツを確認して、期待を満たすことを確認します。
var_dump($serialized_data);
「非立体化できない」エラーは、通常、シリアル化されたデータの整合性、PHPバージョンの非互換性、クラスファイルの欠落、または文字エンコードの問題に関連しています。問題は通常、これらの一般的な原因を1つずつチェックし、対応するソリューションを取得することで解決できます。条件が許可されている場合は、特にクロスプラットフォームまたはバージョンで、シリアル化と脱派化の代わりにJSONを使用することを検討してください。これにより、潜在的な互換性の問題を回避できます。