質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.32%

【FuelPHP】Session::get()が遅い

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 1,032

tampopopofu

score 22

前提・実現したいこと

fuelphpを使って開発をしています。
最近、バージョンを「1.8.0」から「1.8.1」に上げました。
ログイン処理はDBを使用し、認証成功ならセッションにユーザIDを格納しています。
その後の画面遷移ごとにセッションからユーザIDを確認しています。
Authパッケージは使用しています。

発生している問題・エラーメッセージ

ログインチェックする際に、セッションからユーザIDを取得するのですが、「1.8.1」にしてからすごい時間が掛かるようになりました。

該当のソースコード

ログイン成功時にセッションに値を格納。

public function complete_login($user_id) {
    Session::set('user_login', $user_id); // ← ここは速い
    Session::instance()->rotate();
}

画面遷移ごとに行うログインチェック。

// ログインチェック
if (!Auth::check()) {
    Response::redirect('/');
    return;
}


Auth::check()から呼ばれるperform_check()が以下。

protected function perform_check() {
    $this->user = Session::get('user_login'); // ← ここに時間が掛かる
    return !empty($this->user);
}

試したこと

Session::get()しているところに固定値のユーザIDを入れたら前と同じくらいの処理時間になりました。

protected function perform_check() {
    $this->user = 'USER0001'; // ← 固定値にすると速い
    return !empty($this->user);
}

補足情報(FW/ツールのバージョンなど)

「1.8.0」から「1.8.1」にバージョンアップしてSessionクラスを見てみましたが、結構変わっていてどこが原因か特定できませんでした。

処理速度としましては10倍以上の差が出ています。
150msだったのが1,800msになったりとかです。

追加情報

// authのConfigです
<?php
return array(
    'driver' => 'Dbdriver',
    'verify_multiple_logins' => false,
    'salt' => 'dummy_salt',
    'iterations' => 10000,
);


config/config.php

<?php
/**
 * Fuel is a fast, lightweight, community driven PHP 5.4+ framework.
 *
 * @package    Fuel
 * @version    1.8.1
 * @author     Fuel Development Team
 * @license    MIT License
 * @copyright  2010 - 2018 Fuel Development Team
 * @link       http://fuelphp.com
 */

return array(
    // 'base_url'  => null,
    // 'url_suffix'  => '',
    'index_file' => '',
    'profiling'  => false,
    // 'cache_dir'       => APPPATH.'cache/',
    'caching'         => true,
    'cache_lifetime'  => 7200, // In Seconds
    // 'ob_callback'  => null,
    'language'           => 'ja', // Default language
    'language_fallback'  => 'en', // Fallback language when file isn't available for default language
    'locale'             => null,
    'encoding'  => 'UTF-8',
    'server_gmt_offset'  => 0,
    'default_timezone'   => 'Asia/Tokyo',
    'log_threshold'    => Fuel::L_ALL,
    // 'log_path'         => APPPATH.'logs/',
    'log_date_format'  => 'Y-m-d H:i:s',

    /**
     * Security settings
     */
    'security' => array(
        'csrf_autoload'            => false,
        // 'csrf_autoload_methods'    => array('post', 'put', 'delete'),
        // 'csrf_bad_request_on_fail' => false,
        // 'csrf_auto_token'          => false,
        'csrf_token_key'           => 'csrf_token',
        'csrf_expiration'          => 10000,

        /**
         * A salt to make sure the generated security tokens are not predictable
         */
        'token_salt' => 'dummy_token_salt',

        /**
         * Allow the Input class to use X headers when present
         *
         * Examples of these are HTTP_X_FORWARDED_FOR and HTTP_X_FORWARDED_PROTO, which
         * can be faked which could have security implications
         */
        // 'allow_x_headers'       => false,

        /**
         * This input filter can be any normal PHP function as well as 'xss_clean'
         *
         * WARNING: Using xss_clean will cause a performance hit.
         * How much is dependant on how much input data there is.
         */
        'uri_filter'       => array('htmlentities'),

        /**
         * This input filter can be any normal PHP function as well as 'xss_clean'
         *
         * WARNING: Using xss_clean will cause a performance hit.
         * How much is dependant on how much input data there is.
         */
        // 'input_filter'  => array(),

        /**
         * This output filter can be any normal PHP function as well as 'xss_clean'
         *
         * WARNING: Using xss_clean will cause a performance hit.
         * How much is dependant on how much input data there is.
         */
        'output_filter'  => array('Security::htmlentities'),

        /**
         * Encoding mechanism to use on htmlentities()
         */
        // 'htmlentities_flags' => ENT_QUOTES,

        /**
         * Whether to encode HTML entities as well
         */
        // 'htmlentities_double_encode' => false,

        /**
         * Whether to automatically filter view data
         */
        // 'auto_filter_output'  => true,

        /**
         * With output encoding switched on all objects passed will be converted to strings or
         * throw exceptions unless they are instances of the classes in this array.
         */
        'whitelisted_classes' => array(
            'Fuel\\Core\\Presenter',
            'Fuel\\Core\\Response',
            'Fuel\\Core\\View',
            'Fuel\\Core\\ViewModel',
            'Closure',
        ),
    ),

    /**
     * Cookie settings
     */
    // 'cookie' => array(
        // Number of seconds before the cookie expires
        // 'expiration'  => 0,
        // Restrict the path that the cookie is available to
        // 'path'        => '/',
        // Restrict the domain that the cookie is available to
        // 'domain'      => null,
        // Only transmit cookies over secure connections
        // 'secure'      => false,
        // Only transmit cookies over HTTP, disabling Javascript access
        // 'http_only'   => false,
    // ),

    /**
     * Validation settings
     */
    // 'validation' => array(
        /**
         * Whether to fallback to global when a value is not found in the input array.
         */
        // 'global_input_fallback' => true,
    // ),

    /**
     * Controller class prefix
     */
     // 'controller_prefix' => 'Controller_',

    /**
     * Routing settings
     */
    // 'routing' => array(
        /**
         * Whether URI routing is case sensitive or not
         */
        // 'case_sensitive' => true,

        /**
         *  Whether to strip the extension
         */
        // 'strip_extension' => true,
    // ),

    /**
     * To enable you to split up your application into modules which can be
     * routed by the first uri segment you have to define their basepaths
     * here. By default empty, but to use them you can add something
     * like this:
     *      array(APPPATH.'modules'.DS)
     *
     * Paths MUST end with a directory separator (the DS constant)!
     */
    'module_paths' => [
        APPPATH.'modules'.DS
    ],

    /**
     * To enable you to split up your additions to the framework, packages are
     * used. You can define the basepaths for your packages here. By default
     * empty, but to use them you can add something like this:
     *      array(APPPATH.'modules'.DS)
     *
     * Paths MUST end with a directory separator (the DS constant)!
     */
    'package_paths' => array(
        PKGPATH,
    ),

    /**************************************************************************/
    /* Always Load                                                            */
    /**************************************************************************/
    'always_load' => [

        /**
         * These packages are loaded on Fuel's startup.
         * You can specify them in the following manner:
         *
         * array('auth'); // This will assume the packages are in PKGPATH
         *
         * // Use this format to specify the path to the package explicitly
         * array(
         *     array('auth'    => PKGPATH.'auth/')
         * );
         */
        // 'packages'  => array(
        //     //'orm',
        // ),
        'packages'  => [
            'auth',
            'email',
        ],

        /**
         * These modules are always loaded on Fuel's startup. You can specify them
         * in the following manner:
         *
         * array('module_name');
         *
         * A path must be set in module_paths for this to work.
         */
        'modules' => [
            'AAA',
            'BBB',
        ],

        /**
         * Classes to autoload & initialize even when not used
         */
        // 'classes'  => array(),

        /**
         * Configs to autoload
         *
         * Examples: if you want to load 'session' config into a group 'session' you only have to
         * add 'session'. If you want to add it to another group (example: 'auth') you have to
         * add it like 'session' => 'auth'.
         * If you don't want the config in a group use null as groupname.
         */
        // 'config'  => array(),
        'config' => [
     ],

        /**
         * Language files to autoload
         *
         * Examples: if you want to load 'validation' lang into a group 'validation' you only have to
         * add 'validation'. If you want to add it to another group (example: 'forms') you have to
         * add it like 'validation' => 'forms'.
         * If you don't want the lang in a group use null as groupname.
         */
        // 'language'  => array(),
    ],

);

sessionのConfigはdefault(Core)のままで触ってはいません。

<データベース>
xamppの10.1.22-MariaDB、phpMyAdminのバージョンは4.8.5です。

お分かりになる方、どうぞご教授お願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Eggpan

    2019/07/18 01:32

    セッションのコンフィグ設定や、セッションドライバがデータベース利用の場合はDB環境も追記してもらったほうが良い回答が得られると思います。
    時々重くなる、とかであれば gc_probability 設定に関わる動作周りかもしれません。

    キャンセル

  • tampopopofu

    2019/07/20 14:28

    ご助言ありがとうございます。
    Config等の情報を追加しました。

    キャンセル

回答 1

0

直接の回答では無いですが・・。

config/config.phpのprofilerをtrueにすると画面からプロファイラが表示できます。
気になる箇所にProfiler::mark("適当なメッセージ");を挿入するとProfiler内のConsoleタブで実行時間が確認できますので、ソースファイル各所にいれてボトルネックを探してみてはどうでしょうか。

手元の環境で1.8.0と1.8.1を入れてみてSession::getだけ実行する処理で比べてみましたが、どちらも0.01〜0.02秒の間で実行されまして、1割か2割程度1.8.1の方が遅い結果にはなりましたが、速度にそこまでの差はありませんでした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/23 08:47

    CookieドライバでSession::get すると概ね下記のメソッドを通るみたいです。

    Session::_init
    Session::forge
    Session_Cookie::start
    Session_Cookie::_change_state
    Session_Cookie::read
    Session_Cookie::_get_cookie
    Crypt::decode
    Crypt::encode

    キャンセル

  • 2020/03/15 14:03

    ありがとうございます!
    試してみます。

    キャンセル

  • 2020/03/15 14:20

    ajaxでの処理なのでうまくプロファイルが利かないみたいですね。。
    あれからもう一度フレームワークを再DLして入れ替えたところ、アプリの起動直後はやはり1,800ms程度掛かりますが、そのまま何回か動かしていくと300ms~400msに落ち着きます。
    一旦はこのままでいこうと思います。

    あと分かったことは、ブラウザの開発ツールのネットワークを見ると、処理時間のうち、9割は「待機」の時間で占められていました。
    「Session::get」を入れると待機し、無くすと待機がなくなり処理は速いです。
    なんなんでしょうねぇ。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.32%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る