ホームページ  >  記事  >  バックエンド開発  >  アンシリアライズと Autoload_PHP チュートリアル

アンシリアライズと Autoload_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-22 09:03:061191ブラウズ

資格のある PHP プログラマーなら誰でも UnserializeAutoload を知っているはずですが、この 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 が発生すると、悲惨な結果になります。

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";}';


$result = (配列)アンシリアル化($string);


var_dump($result);



? >


クラス定義ファイルが見つからないのでエラーが報告されたのは間違いありません! spl_autoload_register を変更することは確かに可能ですが、サードパーティのコードが関係する場合は、現時点では、自動ロードをバイパスするための決定を行うことができません。最も簡単な方法は、FAKE out に必要なクラスを追加することです:

php

spl_autoload_register(関数($name) {


「/path/to/{$name}.php」を含めます;


});


class Foobar {} // ああ、クソ!


$string = 'O:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';


$result = (配列)アンシリアル化($string);


var_dump($result);


? >上記のコードは本当にでたらめだと言わざるを得ません。だから何をすべきか?実装を大まかに書きました:


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 クラスがなくなり、かなり快適になりました。

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/371813.html技術記事資格のある PHP プログラマであれば、Unserialize と Autoload について知っているはずですが、この 2 つの関係について明確に知っている人は多くないのではないかと思います。 例を挙げましょう、偽物...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。