資格のある PHP プログラマーなら誰でも Unserialize と Autoload を知っているはずですが、この 2 つの関係となると、明確に知っている人は多くないのではないかと思います。
たとえば、サードパーティのシリアル化されたデータを取得できるが、対応するクラス定義がないとします。コードは次のとおりです。
php
$string = 'O:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';
$result = unserialize($string);
var_dump($result);
/*
オブジェクト(__PHP_Incomplete_Class)[1]
public '__PHP_Incomplete_Class_Name' => 文字列 'Foobar' (長さ=6)
public 'foo' => 文字列 '1' (長さ=1)
パブリック 'bar' => 文字列 '2' (長さ=1)
*/
? >オブジェクトを逆シリアル化するときに、オブジェクトのクラス定義が存在しない場合、PHP は不完全なクラスの概念、つまり __PHP_Incomplete_Class を導入します。この時点では、逆シリアル化は成功しましたが、依然としてオブジェクトにアクセスできません。データが存在しない場合、次のエラー メッセージが表示されます:
スクリプトがメソッドを実行しようとしたか、不完全なオブジェクトのプロパティにアクセスしようとしました。操作しようとしているオブジェクトのクラス定義が unserialize() が呼び出される前にロードされていることを確認するか、クラスをロードする __autoload() 関数を提供してください。定義
これは難しい作業ではありません。強制的に型変換を行うだけで配列になります。
php
$string = 'O:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';
$result = (配列)アンシリアル化($string);
var_dump($result);
/*
配列
'__PHP_Incomplete_Class_Name' => 文字列 'Foobar' (長さ=6)
'foo' => 文字列 '1' (長さ=1)
'bar' => 文字列 '2' (長さ=1)
*/
? >
しかし、システムで自動ロードが有効になっている場合、状況はさらに複雑になります。ちなみに、PHP には unserialize_callback_func という設定オプションが用意されていますが、その意味は autoload と似ていますので、ここでは紹介しません。例は次のとおりです。
php
spl_autoload_register(関数($name) {
var_dump($name);
});
$string = 'O:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';
$result = (配列)アンシリアル化($string);
var_dump($result);
? >上記のコードを実行すると、spl_autoload_register がトリガーされることがわかります。ほとんどの場合、これは理にかなっていますが、不適切に定義された spl_autoload_register が発生すると、悲惨な結果になります。
? >
クラス定義ファイルが見つからないのでエラーが報告されたのは間違いありません! spl_autoload_register を変更することは確かに可能ですが、サードパーティのコードが関係する場合は、現時点では、自動ロードをバイパスするための決定を行うことができません。最も簡単な方法は、FAKE out に必要なクラスを追加することです:
php
spl_autoload_register(関数($name) {
「/path/to/{$name}.php」を含めます;
});
$string = 'O:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';
$functions = spl_autoload_functions();
foreach ($functions としての $function) {
spl_autoload_unregister($function);
}
$result = (配列)アンシリアル化($string);
foreach ($functions としての $function) {
spl_autoload_register($function);
}
var_dump($result);
? >コードが少し増えましたが、少なくとも FAKE クラスがなくなり、かなり快適になりました。