1

外部ページの $_SESSION 変数にアクセスできません。

基本的に、私は drupal ノードにフォームを持っています。これは、送信されると、次のように値を $_SESSION 変数に保存する外部 php ファイルに投稿します。

//Bootstrap Drupal so we can use the SESSION variables, where we store the calling number for the
//duration of the logged in session
define('DRUPAL_ROOT', $_SERVER['DOCUMENT_ROOT']);
$base_url = 'http://'.$_SERVER['HTTP_HOST'];
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);

//Save number as the calling number for the session
$_SESSION['calling-number']=$_REQUEST['calling-number'];

それはうまくいきます。

後で、次を使用して外部ページから $_SESSION 変数にアクセスしようとしたとき:

//Bootstrap Drupal so we can use the SESSION variables, where we store the calling number for the
//duration of the logged in session
define('DRUPAL_ROOT', $_SERVER['DOCUMENT_ROOT']);
$base_url = 'http://'.$_SERVER['HTTP_HOST'];
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);

echo $_SESSION['calling-number'];

私は何も得ません。この新しいページの $user を見ると、$_SESSION 変数を設定したログイン ユーザー ID ではなく、匿名ユーザー セッション (uid = 0) で実行されていることがわかります。見つかりません。

ログインしたユーザーのセッションを使用していない理由はありますか?

編集

理由はわかりませんが、2 つの外部ファイルが異なるディレクトリにある限り、これは正常に機能します。それらが同じディレクトリにある場合、新しいセッションを開始し、既存のセッションにはアクセスしないようです。理由はわかりませんが。

4

2 に答える 2

2

私の理解が正しければ、認証されたユーザーがいる Drupal からフォームを外部 PHP ファイルに送信します。Drupal をブートストラップする外部ページからセッションにアクセスしようとすると、セッションには以前に保存された値が含まれず、ユーザーは以前にフォームをコミットした認証済みユーザーではなく、匿名ユーザーであると報告されます。

これは通常、次の理由で発生します。

  • session_name()Drupal は、名前が、およびである Cookie を検出しませんsubstr(session_name(), 1)
    この場合、drupal_session_initialize()は次のコードを実行します。

    // Set a session identifier for this request. This is necessary because
    // we lazily start sessions at the end of this request, and some
    // processes (like drupal_get_token()) needs to know the future
    // session ID in advance.
    
    $GLOBALS['lazy_session'] = TRUE;
    $user = drupal_anonymous_user();
    // Less random sessions (which are much faster to generate) are used for
    // anonymous users than are generated in drupal_session_regenerate() when
    // a user becomes authenticated.
    session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE)));
    if ($is_https && variable_get('https', FALSE)) {
      $insecure_session_name = substr(session_name(), 1);
      $session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE));
      $_COOKIE[$insecure_session_name] = $session_id;
    }
    
  • Drupal は、セッション読み取りコールバック ( _drupal_session_read()$sid )に渡された引数の値と等しい sid (または ssid) のレコードをセッション データベース テーブルに見つけません。これは、セッションの有効期限が切れた場合にも発生する可能性があります。

    if ($is_https) {
      $user = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.ssid = :ssid", array(':ssid' => $sid))->fetchObject();
      if (!$user) {
        if (isset($_COOKIE[$insecure_session_name])) {
          $user = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid AND s.uid = 0", array(
            ':sid' => $_COOKIE[$insecure_session_name],
          ))
          ->fetchObject();
        }
      }
    }
    else {
      $user = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid", array(':sid' => $sid))->fetchObject();
    }
    

Drupal は、PHP のシャットダウン時に_drupal_session_write()を介して常に現在のユーザーのセッションを保存します。これは、現在のユーザーが匿名ユーザーの場合にも行われます。

   if (!drupal_save_session()) {
      // We don't have anything to do if we are not allowed to save the session.
      return;
    }

    // Check whether $_SESSION has been changed in this request.
    $last_read = &drupal_static('drupal_session_last_read');
    $is_changed = !isset($last_read) || $last_read['sid'] != $sid || $last_read['value'] !== $value;

    // For performance reasons, do not update the sessions table, unless
    // $_SESSION has changed or more than 180 has passed since the last update.
    if ($is_changed || !isset($user->timestamp) || REQUEST_TIME - $user->timestamp > variable_get('session_write_interval', 180)) {
      // Either ssid or sid or both will be added from $key below.
      $fields = array(
        'uid' => $user->uid, 
        'cache' => isset($user->cache) ? $user->cache : 0, 
        'hostname' => ip_address(), 
        'session' => $value, 
        'timestamp' => REQUEST_TIME,
      );

      // Use the session ID as 'sid' and an empty string as 'ssid' by default.
      // _drupal_session_read() does not allow empty strings so that's a safe
      // default.
      $key = array(
        'sid' => $sid,
        'ssid' => '',
      );

      // ...

      db_merge('sessions')
        ->key($key)
        ->fields($fields)
        ->execute();
    }
于 2012-11-11T17:15:27.663 に答える