質問

実際にできることに今気づきました オブジェクトを $_SESSION に保存する 別のページにジャンプしてもオブジェクトがまだ残っているので、これは非常に素晴らしいと思います。このアプローチを使用する前に、それが本当に良いアイデアなのか、それとも 潜在的な落とし穴 関与した。

単一のエントリ ポイントがあれば、その必要がないことはわかっていますが、私はまだそこに到達していないので、単一のエントリ ポイントを持っていません。オブジェクトを保持しておきたいと思っています。そんなふうに私の状態を失うことはありません。(ステートレス サイトをプログラムする必要があるということも読みましたが、その概念はまだ理解していません。)

それで 要するに:セッションにオブジェクトを保存しても問題ありませんか?


編集:

暫定まとめ:今ではおそらくそうだと理解しています 作り直した方が良い データベースへの再度のクエリが必要な場合でも、オブジェクトは削除されません。

さらなる答えはおそらく その面について詳しく説明する もうちょっと!

役に立ちましたか?

解決

このトピックが古いことは承知していますが、この問題は常に浮上しており、満足のいく解決が得られていません。

オブジェクトを $_SESSION に保存する場合でも、非表示のフォーム フィールドに隠されたデータに基づいてオブジェクト全体を再構築する場合でも、毎回 DB からオブジェクトを再クエリする場合でも、状態を使用することになります。HTTP は (多かれ少なかれ) ステートレスです。ただし、「GET 対」を参照してください。PUT) しかし、誰もが Web アプリで行うことのほとんどすべては、どこかに状態を維持する必要があります。国家を隅々まで追い込むことが、ある種の理論上の勝利に相当するかのように振る舞うことは、まったく間違っている。状態は状態です。ステートを使用すると、ステートレスであることで得られるさまざまな技術的利点が失われます。これは、寝不足になると事前にわかっていない限り、寝不足になるようなことではありません。

私は特に、ハンク・ゲイが提起した「二重の打撃」の議論によって受け取られた祝福に当惑しています。OP は分散型で負荷分散された電子商取引システムを構築していますか?私の推測ではノーです。そして私はさらに、彼の $User クラスなどをシリアル化しても、彼のサーバーが修復できないほど機能不全に陥ることはないと仮定します。私のアドバイス:アプリケーションに適したテクニックを使用してください。$_SESSION 内のオブジェクトは、常識的な予防策に従って問題ありません。あなたのアプリが、サービスされるトラフィックにおいて突然 Amazon に匹敵するものになった場合、再適応する必要があります。それが人生。

他のヒント

session_start() 呼び出しが行われるまでに、クラスの宣言/定義が PHP によってすでに検出されているか、すでにインストールされているオートローダーによって検出できる限り、問題はありません。そうしないと、セッション ストアからオブジェクトを逆シリアル化できなくなります。

HTTP がステートレス プロトコルであるのには理由があります。セッションは状態を HTTP に結合します。経験則として、セッション状態の使用は避けてください。

アップデート:HTTP レベルではセッションという概念はありません。サーバーは、クライアントに一意の ID を与え、リクエストごとにそれを再送信するようにクライアントに指示することでこれを提供します。次に、サーバーはその ID をキーとして使用して、Session オブジェクトの大きなハッシュテーブルを作成します。サーバーはリクエストを受け取るたびに、クライアントがリクエストとともに送信した ID に基づいて、セッション オブジェクトのハッシュテーブルからセッション情報を検索します。このような余分な作業はすべて、スケーラビリティにとって二重の打撃になります (これが、HTTP がステートレスである大きな理由です)。

  • ワーミーワン:これにより、単一サーバーが実行できる作業が軽減されます。
  • ワーミー 2:古いサーバーにリクエストをルーティングするだけでは済みません。すべてのサーバーが同じセッションを持っているわけではないため、スケールアウトが難しくなります。特定のセッション ID を持つすべてのリクエストを同じサーバーに固定できます。これは簡単ではなく、単一障害点になります (システム全体ではなく、大部分のユーザーにとって)。または、クラスター内のすべてのサーバー間でセッション ストレージを共有することもできますが、今度はさらに複雑になります。ネットワーク接続メモリ、スタンドアロン セッション サーバーなど。

これらすべてを考慮すると、セッションに入力する情報が多ければ多いほど、パフォーマンスへの影響は大きくなります (Vinko が指摘しているように)。また、Vinko が指摘しているように、オブジェクトがシリアル化可能でない場合、セッションは誤動作します。したがって、経験則として、セッションに絶対に必要なもの以上のものを入れないようにしてください。

@Vinko 通常、送り返す応答に追跡しているデータを埋め込み、クライアントにそれを再送信させることで、サーバーに状態を保存させることを回避できます(たとえば、データを非表示の入力で送信します)。もし、あんたが 本当に サーバー側で状態を追跡する必要がある場合、それはおそらくバッキング データストア内にあるはずです。

(ヴィンコはこう付け加えた:PHP はセッション情報の保存にデータベースを使用でき、クライアントが毎回データを再送信することで潜在的なスケーラビリティの問題は解決される可能性がありますが、クライアントがすべての状態を制御しているため、注意を払う必要があるセキュリティ上の問題が大きく発生します)

  • シリアル化できない (またはシリアル化できないメンバーを含む) オブジェクトは、期待どおりに $_SESSION から取得されません。
  • 巨大なセッションはサーバーに負担をかける (メガステートを毎回シリアル化および逆シリアル化するのはコストがかかる)

それ以外は特に問題は見当たりませんでした。

私の経験では、いくつかのプロパティを備えた StdClass よりも複雑なものには通常、価値がありません。アンシリアル化のコストは常に、セッションに保存された識別子を指定してデータベースから再作成する以上のコストがかかりました。クールに思えますが、(いつものように) プロファイリングが鍵となります。

どうしても必要な場合以外は、state を使用しないことをお勧めします。セッションを使用せずにオブジェクトを再構築できる場合は、それを実行してください。Web アプリケーションに状態があると、リクエストごとにユーザーがどのような状態にあるかを確認する必要があるため、アプリケーションの構築がより複雑になります。もちろん、セッションの使用を避けられない場合もあります (例:ユーザーは、Web アプリケーションでのセッション中にログインを維持する必要があります)。最後に、大きなオブジェクトのシリアル化とシリアル化解除はパフォーマンスに影響を与えるため、セッション オブジェクトをできるだけ小さくしておくことをお勧めします。

リソース タイプ (データベース接続やファイル ポインターなど) はページの読み込み間では保持されず、目に見えないように再作成する必要があることに注意する必要があります。

また、セッションのサイズも考慮してください。セッションの保存方法によっては、サイズ制限や遅延の問題が発生する可能性があります。

ソフトウェア ライブラリをアップグレードするときにも話題になります。ソフトウェアをアップグレードしたところ、古いバージョンには V1 ソフトウェアのクラス名を持つセッション内のオブジェクトがあり、新しいソフトウェアはセッション内にあったオブジェクトを構築しようとするとクラッシュしていました。V2 としてソフトウェアは同じクラスをもう使用していないため、それらを見つけることができませんでした。セッション オブジェクトを検出し、見つかった場合はセッションを削除し、ページをリロードするための修正コードを追加する必要がありました。最初に最大の苦痛となったのは、このバグが最初に報告されたときにこのバグを再現していたのではないかということです (あまりにもよく知られている、「まあ、私にはうまくいきました」:)。このバグは、最近新旧のシステムを出入りしている人々にのみ影響を及ぼしたためです。しかし、良いことです。すべてのユーザーがセッションに古いセッション変数を持っているはずで、すべてのユーザーがクラッシュする可能性があったため、起動前にそれを見つけました。ひどい起動になっていたでしょう:)

とにかく、修正案で提案されているように、オブジェクトを再作成した方が良いと私も思います。したがって、IDを保存し、各リクエストでデータベースからオブジェクトを取得する方が良い/安全かもしれません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top