Пользовательские обработчики сеансов и session.upload_progress - PullRequest
0 голосов
/ 28 января 2020

Моя компания наконец-то перешла на PHP, и нам потребовались пользовательские сеансы, управляемые базой данных. Итак, я создал класс, который вставляю ниже (без чувствительных имен баз данных / таблиц)

Проблема, с которой я столкнулся сейчас, заключается в том, что мы хотели бы реализовать систему выгрузки файлов с проверкой прогресса через встроенную систему session.upload_progress, но пользовательский сеанс уничтожает эту функциональность. Когда я использую базовый сеанс, он работает, когда я использую этот сеанс, это не так. Я предполагаю, что я могу обойти это путем расширения SessionHandler и использования родительских методов, кажется ли это правильным или я все это делаю неправильно? (Очень плохо знаком с PHP, поэтому я подумал, что спрашивать не повредит).

<?php
  class Session {
    private $user_id;
    private $last_login;
    private $database;
    public $user;
    public $username;

    public const MAX_LOGIN_AGE = 60 * 60 * 24; // 1 day

    // Constructor which attaches pseudo magic methods to php sessions
    public function __construct()
    {
      session_set_save_handler(
        array($this, '_open'),
        array($this, '_close'),
        array($this, '_read'),
        array($this, '_write'),
        array($this, '_destroy'),
        array($this, '_clean')
      );

      session_start();
      $this->check_stored_login();
    }

    public function _open()
    {

      if ($session_db = db_connect(DB_DEV)) {
        $this->database = $session_db;
        return true;
      }

      return false;
    }

    public function _close()
    {
      // print "Session closed.\n";

      return $this->database->close();
    }

    public function _read($id)
    {
      $id = $this->database->escape_string($id);

      // print "Session read.\n";
      // print "Sess_ID: $id\n";

      $sql = "SELECT data
              FROM sessions
              WHERE id = '{$id}'";

      if ($result = $this->database->query($sql)) {
        if ($result->num_rows) {
          $record = $result->fetch_assoc();

          return $record['data'];
        }
      }

      return '';
    }

    public function _write($id, $data)
    {
      $access = time();

      $id = $this->database->escape_string($id);
      $access = $this->database->escape_string($access);
      $data = $this->database->escape_string($data);
      // print "Session value written.\n";
      // print "Sess_ID: $id\n";
      // print "Data: $data\n\n";

      $sql = "REPLACE
              INTO sessions (`id`, `access`, `data`)
              VALUES ('{$id}', '{$access}', '{$data}')";

      $this->database->query($sql);

      return true;
    }

    public function _destroy($id)
    {
      $id = $this->database->escape_string($id);

      // print "Session destroy called.\n";

      $sql = "DELETE
              FROM sessions
              WHERE id='{$id}'";

      return $this->database->query($sql);
    }

    public function _clean($max)
    {
      $old = $time() - $max;
      $this->database->escape_string($old);

      $sql = "DELETE
              FROM sessions
              WHERE access < '{$old}'";

      return $this->database->query($sql);
    }

    public function login($user)
    {
      if ($user) {
        // prevent session fixation attacks
        session_regenerate_id();
        $this->user_id = $_SESSION['user_id'] = $user->id = $user->id;
        $this->username = $_SESSION['username'] = $user->first_name;
        $this->last_login = $_SESSION['last_login'] = time();
        $this->user = $_SESSION['user'] = $user;
        $_SESSION['search_text'] = '';
        $_SESSION['search_product_id'] = '';
        $args["last_login"] = date("Y-m-d H:m:s");
        $user->merge_attributes($args);
        $user->save();
      }
    }

    public function is_logged_in()
    {
      if (!isset($this->user_id) || !$this->last_login_recent()) {
        redirect_to(url_for('/index.php?logout'));
      }

      return true;
    }

    public function logout()
    {
      unset($_SESSION['user_id']);
      unset($_SESSION['username']);
      unset($_SESSION['last_login']);
      unset($_SESSION['user']);
      unset($this->user_id);
      unset($this->username);
      unset($this->last_login);
      unset($this->user);
      session_destroy();

      return true;
    }

    private function check_stored_login()
    {
      if (isset($_SESSION['user_id'])) {
        $this->user_id = $_SESSION['user_id'];
        $this->username = $_SESSION['username'];
        $this->last_login = $_SESSION['last_login'];
        $this->user = $_SESSION['user'];
      }
    }

    private function last_login_recent()
    {
      if (!isset($this->last_login)) {
        return false;
      } elseif ($this->last_login + self::MAX_LOGIN_AGE < time()) {
        return false;
      } else {
        return true;
      }
    }

    public function message($msg = '')
    {
      if (!empty($msg)) {
        $_SESSION['message'] = $msg;
      } else {
        return $_SESSION['message'];
      }
    }
  }
?>
...