OKWebでは自己フォローができないみたいなので,改めます.QNo.63140,PHPカテゴリでの通しNo.32の質問の続きです.って言うか自己レス.
質問文中で大きな間違いをしているのがとても恥ずかしいので,訂正します.
> setCookie( "cookie", serialize($obj), mktime("2010/8/1 00:00:00") );
mktime()ではなく,strtotime()です.何をやってるんだ俺は.
それから,実験ですが,オブジェクトのunserialize()時に同名のクラスの定義があっても,そのクラスのインスタンスとしては取り扱ってくれませんでした.
せっかくserialize()時にクラス名まで保存しているんだから,同名のクラス定義があったら読みに行ってくれたらいいのになぁ.
という,ぼやき混じりの無意味な自己レスでした.以上.回答してくださった方(a-kumaさんだけ?),どうもありがとうございました.
No.3ベストアンサー
- 回答日時:
>PHPLIBのserialize()は,確か特定のクラスのメソッドとして実装されていましたよね・・・.そのクラスの各サブクラスは,serialize()を各々オーバーロードしてたんでしょうか・・・
えーと、使い方はこのserializeを持つクラスを継承して使うわけではありません
このserialize機能を持つクラスはセッション管理機能のクラスで
ページの最初にpage_open(array("sess" => "session管理クラス名");
ページの最後にpage_close();
を呼び出すことによりその間で$sess->register("変数名");($sessはグローバルなオブジェクト、page_openのセッション管理クラスで指定されたクラスのインスタンス)
としてやることによりpage_close()時にメンバ関数のregisterで登録したオブジェクトをserializeし、次にpage_open()されたときにunserializeされるようになってます。
よってserializeするオブジェクトにはセッションクラスを継承する必要はありません
ただ、PHP3ではクラスの名前とメンバ変数の名前を取得することができないのでserializeされるクラスに$classnameと$persistent_slotsいうメンバ変数が必要です
$classnameにはクラスの名前を、また、$persistent_slotsにメンバ変数の名前を配列として入力しなくてはなりません
ex.
class hogehoge {
var $classname = "hogehoge";
var $foo;
var $bar;
var $baz;
var $persistent_slots = array("foo", "bar", "baz");
/* 以下 メンバ関数の定義などが続く・・・ */
...
}
PHP内では
<?
page_open("sess" => "session");
$fugafuga = new hogehoge;
$sess->register("fugafuga");
...適当にいろいろな処理...
page_close();
?>
としてやれば、別ページでpage_open()された時点でオブジェクト$fugafugaが再生されます
使い方はこんなとこです
実際に中での動作は・・・というと
$hogehogeをserializeしたいとする
$sess->register("hogehoge");としておくと・・・
ここからserialize...
global $hogehoge;
// 実際には$hogehogeも変数に入った文字列なのでevalを用いなければいけない
$serialize_opcode = "\$hogehoge = new $hogehoge->classname;";
while($variable = each($hogehoge->persistent_slots))
{
$serialize_opcode .= "\$hogehoge->" . $variable . " = " . eval("\$hogehoge->$variable") . ";";
}
としてやって何らかの方法でこの$serialize_opcodeを別のページに持っていってやり(PHPLIBではcookieまたはget methodでunique idを発行してそのidとDBのserial値を適合させることによりページ間移動を実現しています)、受け取ったページでeval($serialize_opcode);としてやれば$hogehogeが使える・・・というわけです
ちなみに実際のserializeのコードはもっと複雑です。メンバ中に配列やクラスがある場合、再帰処理でどんどんもぐってserializeしなくてはいけませんので・・・
>serialize()がある程度各クラスに対してポータブルにかかれていたんでしょか?.
基本的にPHPには3つのデータ型しかありません
スカラ型、配列、オブジェクトです
スカラ型は変数名がわかれば値が取得できるため、永続化は容易です
配列も変数名がわかれば、eachで全メンバが取得できます。ハッシュも同様。
オブジェクトが問題で上記のようにクラス名、およびメンバ名の一覧がないと永続化が不可能です(言語仕様でサポートされれば別ですが・・・)
よってこの3つを再帰的にたどることができればどのようなデータ型もserializeすることが可能です(実際には参照でループリング作ったら永久ループすると思いますが・・・)
>そう言えば,クラス間キャストが出来ないとなると,いわゆる「多態性」ってやつはどうなるんですか?.
あんまりPHPにそういうものを期待しないってのが一番の解決法です(^^;
PHP4ではどうか知りませんがPHP3ではデストラクタすらありませんでした・・・
ちょっと忘却してしまいましたが、ほかにも結構変なところはありましたよ・・・
C++な感じで組んでると痛い目を見ることは確かです(^^;
この回答への補足
まず,非常にご丁寧なご返事に感謝します.ここまで教えていただけるとは思っていませんでした.いまさらこんなことを言ってしまうとご気分を害されるかもしれませんが,質問内容が途中から(アルバイトの)仕事とは関係のない,興味本位のものになっていました.申し訳ありません.ひょっとして気づいておられたかもしれませんが,それでも付き合っていただいたことに,お礼を申し上げます.
ご返事をいただいてから「しまった!」と思ったのですが,本来避けるべき手取り足取りのご返事をいただくような質問をして,少し反省をしております.
> ページの最初にpage_open(array("sess" => "session管理クラス名");
> ページの最後にpage_close();
> を呼び出すことによりその間で$sess->register("変数名");($sessはグローバルなオブジェクト、> page_openのセッション管理クラスで指定されたクラスのインスタンス)
> としてやることによりpage_close()時にメンバ関数のregisterで登録したオブジェクトを
> serializeし、次にpage_open()されたときにunserializeされるようになってます。
ここのところの概念がよくわかっていなかったので,妙な質問をしました.Sessionクラスのインスタンスは自分以外の変数,オブジェクトのserialize(),unserialize()を行うために,各ページごとに生成されるオブジェクトだったのですね.
> $classnameにはクラスの名前を、また、$persistent_slotsにメンバ変数の名前を配列として
> 入力しなくてはなりません
a-kumaさんからメンバ変数の復活(unserialize()された「擬似」オブジェクトからのコピー)のためのメソッド,というアドバイスを頂いたとき,これと同じようなことを僕も考えました.しかし,serialize()を施したいクラスそれぞれに関していちいちそのほう名メンバを定義するのも,スマートじゃない気がしますし,こういう機能はむしろ,ユーザ側のライブラリではなく,言語処理系の側で実装する昨日のように思われます.
それにPHP4のserialize()に一応,クラス名というシンボルが残されている以上,こちらを使ったほうがいいのでは,と今は思っています.ただし,ご指摘を受けるまでオブジェクト型のメンバ変数の参照先,というところまでは考えが及びませんでしたが・・・(どうしよう).
> オブジェクトが問題で上記のようにクラス名、およびメンバ名の一覧がないと永続化が不可能です
> (言語仕様でサポートされれば別ですが・・・)
まさしく.
それから・・・.
> そう言えば,クラス間キャストが出来ないとなると,いわゆる「多態性」って
> やつはどうなるんですか?.
自分で書いといて何ですが,この質問は無意味だったと思います.多重継承やインターフェースのような実装されていない機能についてはともかく,PHP4のオブジェクトへの参照型変数は,おっしゃるようにそれ以上の「型」なんてありませんから,相手がどんなクラスであろうと与えられたシンボルのメソッドを探しに行くんですよねぇ.
if( condition_A ){
$obj = new ClassA();
}else if( condition_B ){
$obj = new ClassBNoRelationshipWithClassA();
// ClassAとは全く継承関係のないClassB
}else{
$obj = new ClassCExtendsClassA();
// ClassAのサブクラスClassC
}
$result = $obj->method_name();
// 各クラスにmethod_name()がありさえすれば
// エラーは出ない
あたりまえのことでした.これが型チェックがないことの副作用か,ポリモーフィズムへの指向かは知りませんが.(ひょっとして僕は「多態性」を誤解してますでしょうか?)
いずれにせよ,今回の質問ではいちいち丁寧なご回答をいただき,本当に感謝しております.ありがとうございました.
No.2
- 回答日時:
つい先日までPHPで仕事をしてました
んと、serializeがあるって事は多分PHP4なのでしょうか?
こちらはPHP3+i18nパッチ+PHPLIBでやってましたが
PHPLIBの中に変数の永続化の機能があり、その中でclassのsirialize、unsirializeもしてましたよ
やり方はserializeでクラスの内容を読みこみ再構築コードを文字列として作成し、unserialize時にそれをevalする、と言う手法を取っていました
なので、クラス定義はunserialize前に自分で読んでおく必要がありました
元質問の方を見た限り、PHPLIBの手法でやれば解決できると思います
とりあえずPHPLIBをダウンロードしてソースコードを眺めてみてはいかがでしょうか?
確か、session.incのserialize()がメンバ関数として定義してありますのでその辺を見てください
PHPLIBの解説、マニュアルの日本語版、ダウンロード場所は参考URLを見てください
参考URL:http://www.php.gr.jp/php/phplib/
この回答への補足
> その中でclassのsirialize、unsirializeもしてましたよ
> やり方はserializeでクラスの内容を読みこみ
> 再構築コードを文字列として作成し、unserialize時に
> それをevalする、と言う手法を取っていました
なるほど.とりあえずphpの標準ライブラリの仕様はそんなに読み込んでいないので,具体的にどういうコードになっているのかちょっと想像がつきませんが,「読めば多少は理解」出来そうな感じ(ほんとか?)ですね.
それでは,読ませていただきます.
「ひとりごと」.
PHPLIBのserialize()は,確か特定のクラスのメソッドとして実装されていましたよね・・・.そのクラスの各サブクラスは,serialize()を各々オーバーロードしてたんでしょうか・・・,それとも,元のserialize()がある程度各クラスに対してポータブルにかかれていたんでしょか?.
そう言えば,クラス間キャストが出来ないとなると,いわゆる「多態性」ってやつはどうなるんですか?.
No.1
- 回答日時:
> mktime()ではなく,strtotime()です.何をやってるんだ俺は
よくあることです :-)
CGIのデバッグ中に、cookieが保存されてなくて、うんうんうなって
三日くらいたってから localhost だと cookie が保存されないと
いうことを知って昇天した奴を知ってます >俺だ (^^;
PHPも、そこここで見かけるようになりましたので、きちんと
オブジェクトのシリアライズができる(*)ようになるのは、そんなに
遠いことではない、と期待してます。
(*) オブジェクトのシリアライズで、クラスを復元しない
というのは、ちょっと納得できんですが
perl でも、(見かけ上)オブジェクトを扱えるので、PHPも
オブジェクト(らしいもの)を扱えない、というわけにはゆかず、
おまけ程度でもつけた、という感じですものね。
あの後、ちょっと思いついたのですが、それなりに需要のある
クラスなのであれば、unserialize()+属性のコピーを受け持つ
Factory クラスを実装しておく、というのが良いのかなあ、
と思ってます。
もう一つは、クラスも復元をするように stanaka さんが patch
をあてて、本家に取り込んでもらうという手も :-)
# ぼやきに共感する a-kuma でした
この回答への補足
> よくあることです :-)
> CGIのデバッグ中に、cookieが保存されてなくて、うんうんうなって
> 三日くらいたってから localhost だと cookie が保存されないと
> いうことを知って昇天した奴を知ってます >俺だ (^^;
これとは違いますが,phpをはじめて触ると,1ファイルが1ページと同期して動く,ということが理解しにくい場合があります.私は,頭のほうでsetCookie()とかやっといて,ページをもう一度読みなおさずに必死でCookie変数を探していたことがありました.(そんなバカな!!)
> perl でも、(見かけ上)オブジェクトを扱えるので、PHPも
> オブジェクト(らしいもの)を扱えない、というわけにはゆかず、
> おまけ程度でもつけた、という感じですものね。
そうなんですか,残念ですねぇ.
> もう一つは、クラスも復元をするように stanaka さんが patch
> をあてて、本家に取り込んでもらうという手も :-)
ははぁ,そう来ますか(笑).当方,まだ処理系のソースをハックするほど手馴れたプログラマではないんですが,勉強がてら,ひまを見つけてやってみることにしましょうかねぇ.それともphp自身で実装できそうですか?.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP PHPで訪問回数を表示するカウンタを作成したい 3 2023/05/27 07:09
- 哲学 自分を肯定したいのは誰だって同じじゃないでしょうか? 認知症の特番で「どのような人であれ、生きるとは 5 2022/05/23 18:02
- C言語・C++・C# C# 継承の問題で programに示された拡張をすべて含んだ上で,クラス Mammal に,そのオ 1 2022/07/22 09:48
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/17 18:41
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/06 09:28
- 日本語 複合名詞(造語)について教えて欲しいです 2 2022/05/22 17:14
- その他(悩み相談・人生相談) 新学期が始まもなく子供のクラス懇談会 自己紹介で緊張してしまいます。 4 2023/04/27 11:52
- 友達・仲間 友人について 厳しい意見お待ちしております。 私は結構わがままだししつこいしプライドが高いという自己 3 2022/11/17 16:26
- その他(プログラミング・Web制作) このプログラミングをどう組みますか? Googlecolabでやってるんですが、出来る方お願いします 1 2022/07/13 10:52
- 世界情勢 他人の考え方や意見などを求めておきながら、頭から否定するなら質問するな 8 2022/09/19 11:28
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
'_'(アンダースコア)の使い方...
-
phpのクラスメソッドの定義が長...
-
PHP4、PHP5 1ファイル複数クラ...
-
ラッパークラスって何ですか?
-
phpでPEAR::DBを使っているので...
-
onedrive にexcelファイルをア...
-
index.phpって何ですか? 具体...
-
index.phpに入るには、どうすれ...
-
PHP8を使うと、大量のWarningが...
-
トランザクションが原因?DBに...
-
エックスサーバーでのmysql設定...
-
パースエラーとは?
-
フォントの色を変えるには?
-
ImageCreate関数が undefined f...
-
入力フォームの空白や改行を制...
-
別ファイルの変数を呼び出した...
-
php5-extensions を make でき...
-
★PHP?★画像を縦横比を変えずに...
-
PHPのif文でその処理を途中で抜...
-
PHPのみでの背景色は指定できる...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「クラス関数」「メンバ関数」...
-
ラッパークラスって何ですか?
-
phpのクラスメソッドの定義が長...
-
class定義のphpをファイル分割...
-
PHP4、PHP5 1ファイル複数クラ...
-
phpのクラスにて別ファイルの変...
-
'_'(アンダースコア)の使い方...
-
コンストラクタで参照渡しをす...
-
データベースで値をインクリメ...
-
クラス
-
【PHP】クラス と 関数 の違い
-
ユーザ定義関数にデフォルト引...
-
PHPのフレームワークの中でSmar...
-
phpのオブジェクトの使用方法に...
-
phpでクライアントのブラウザの...
-
配列とオブジェクトの違い
-
POSTとGET
-
Codeigniter コアクラスの継承
-
外部ファイルのクラスのインス...
-
class.upload.phpの戻り値(返...
おすすめ情報