1

PHP で今まで見た中で最も奇妙な問題に直面しています。各詳細が重要になる可能性があるため、私は本当に徹底的にしようとします.

3 つの PHP ページがあり、それらの HTML は Smarty を使用して生成されます。session_start()彼らは皆、自分のトップを呼びます。

  • 最初のページは読み込みが重い場合があります。PHP の複雑なオブジェクトのプレビューであるクリック可能な画像が大量に表示されます。
  • 画像を選択すると、特定の URL を持つ 2 番目のページに移動します。このページは、URL 情報に関連する PHP オブジェクトを生成します (したがって、このページは前のページの情報を必要としません。この URL をいつでも動作します)。$_SESSIONこのオブジェクトは一意の IDで格納されます。
  • 3 ページ目は、2 ページ目の HTML コード (Smarty で生成) に img src として含まれています。これは、URL パラメーターにオブジェクトのセッション ID を持ち、$_SESSION でオブジェクトの情報を読み取り、イメージ プレビューを作成し、ヘッダー ('Content-type: image/jpeg') を持つイメージに変換する PHP ページです。

要約すると、重い最初のページ => 2 番目のページで PHP オブジェクトを作成して保存する$_SESSION=> 2 番目のページの HTML コードに含まれる 3 番目のページで、このオブジェクトを検索してプレビューを作成します。

問題は、この 3 番目のページがオブジェクトをロードしようとして、$_SESSIONそこにないことです。

いくつかの事実 :

  • 2 番目のページが独自の URL を持つスタンドアロンとして読み込まれる場合、問題は発生しません。
  • この問題は、重い最初のページが画像の読み込みを開始し、表示される最初のページのいずれかを猛烈にクリックしたときにのみランダムに発生します
  • 状況がどうであれ$_SESSION、2 ページ目の最後で変数をダンプすると、セッションで生成されたオブジェクトを常に見ることができます。

したがって、問題は 2 ページ目の最後と 3 ページ目の最初の間にあるようですが、これはすべて最初のページのアクティビティに関連しています。私が知っているのは、それがページ間の高速ナビゲーションにリンクされているということだけです.

私はほとんどすべてを試しました:

  • session_write_close()可能な限りどこでも(スマート表示の前/後のページの最後、次に最初の前にsession_start()
  • exit()スクリプトの最後に追加
  • sleep(1)セッションのクローズ操作にさらに時間が必要な場合は、3 番目の開始時でも

何も機能しません。もう手がかりはありません...多分Smarty?バグ #4454 という名前の奇妙な PHP セッションの動作がどこかにあるのではないでしょうか?

これを手伝ってくれてありがとう。

serialize()編集:チャット後のコード

/* ===== Page2.php ===== */

/* オブジェクト $card を作成し、いくつかの値を設定しています ...*/

/*カードのプレビューを表示する関数の呼び出し*/
$assigns['front'] = $card->getPreviewURL();

/*その他 ... $assigns を smarty に割り当てる ... etc*/


/* ===== カード オブジェクト クラス ===== */

関数 getPreviewURL()
{
  $_SESSION['products'][$this->getObjectId()] = serialize($this);
  $url = '/page3.php?s='.$this->getObjectId();
  $url を返します。
}


/* ===== Page2.html ===== */

img src="{$front}" alt="toto"


/* ===== Page3.php ===== */

/*id 値の取得とセッションの読み取り*/

if(!empty($_GET['s'])) {
  session_write_close();
  $session = 新しいセッション;
  if(!empty($_SESSION['products'][$_GET['s']])) {
     $product = unserialize($_SESSION['products'][$_GET['s']]);
  }
  そうしないと {
     log('$_SESSION[製品]['.$_GET['s'].'] は存在しません');
     header("ステータス: 404 見つかりません");
     出口;
  }
}

バグが発生すると、次のようになります。

page2.php デバッグ ログ:
セッション値: [o20aee110e0853e74da4d17c9b7ab3075]=>O:8:"Postcard":19:{s:4:"tmpl";O:16:"PostcardTemplate":20:{s:2:"id";s:3: "152";s:2:"or";i:0;s:3:"ord";s:2:"14";s:11:"説明";s:0:"" ... など
page3.php デバッグ ログ:
$_SESSION[製品][o20aee110e0853e74da4d17c9b7ab3075] は存在しません
4

1 に答える 1

1

おそらく問題は、PHP がオブジェクトのシリアル化を解除しようとするが、クラス定義が見つからないことです。

次の 2 つのいずれかを行うことができます。

オブジェクトをセッションに入れる前に手動でserialize()し、クラス定義をロードした後にunserialize()します。

または: autoloadingを使用します。

于 2011-06-22T16:09:26.603 に答える