読者です 読者をやめる 読者になる 読者になる

Thanks Driven Life

日々是感謝

PHP 5.4 以上でも register_globals と生きていくために $_SESSION のことも忘れてはいけない

忘れたい(切実)

経緯

PHP 5.4 以上でも register_globals と生きていくために - Thanks Driven Life

上記ポストで register_globals を再現する関数をご紹介しました。ですがこれらはあくまでも、いわゆる EGPCS にだけ対応していました。 というかそれで充分と思っていました。

ですが忘れていたのです。$_SESSION の存在を!

結論から言うと

session_start() 直後に

<?php

foreach (array_keys($_SESSION) as $key) {
    $GLOBALS[$key] =& $_SESSION[$key];
}

こうすればいい

対象

  • PHP 5.4 で セッションを扱う register_globals = On 前提のコードの守人たち

register_globals = On だと $_SESSION はどうなるの

PHP 5.3.29 の session.c をざっと眺めてみました。

  1. session_start() する
  2. ↑ の中で php_session_initialize() が呼ばれる
  3. ↑ の中で php_session_decode() が呼ばれる
  4. ↑ の中で PS_SERIALIZER_DECODE_FUNC(php_binary) もしくは PS_SERIALIZER_DECODE_FUNC(php) が呼ばれる
  5. ↑ のどちらの中でも PS_ADD_VARL は呼ばれており、その実体は php_add_session_var() である
  6. ↑ の中で $GLOBALS に変数をセットしていっている(リファレンス張ってる)

つまり

  1. session_start すると
  2. セッションデータをデコードして
  3. デコードして得られたデータ(key-value)を for で回し、$GLOBALS[key] = value とセットしていく
    • 正確には $GLOBALS[$key] =& $_SESSION[$key] みたいな感じ

こんな感じです。

まとめ

がんばるぞい