Claude Skill

bitrix-sessions

Covers Bitrix sessions — Application::getSession(), getKernelSession(), getLocalSession(), BX_SECURITY_SESSION_READONLY and BX_SECURITY_SESSION_VIRTUAL modes, storages (cache, database, redis, null session handler), separated session mode in .settings.php. Applied instead of dire

LLM Mart · 0 points · 10 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download bxmaximum-bitrix-framework-skills-skills_bitrix-sessions-66c40e0.zip · 2 KB
Part of bxmaximum/bitrix-framework-skills — 38 skills

Install

skills CLI npx skills add https://github.com/bxmaximum/bitrix-framework-skills/tree/main/skills/bitrix-sessions
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install bxmaximum-bitrix-framework-skills@llmmart
Git git clone https://github.com/bxmaximum/bitrix-framework-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole bxmaximum/bitrix-framework-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Bitrix Sessions

Directly accessing $_SESSION breaks non-functional modes (readonly, virtual session, separated session) and tests. Use the Session API.

use Bitrix\Main\Application;

$session = Application::getInstance()->getSession();

if (!$session->has('cart'))
{
    $session->set('cart', ['items' => []]);
}

$session['cart']['items'][] = $productId;
$session['cart'] = $cart; // set via ArrayAccess

$session->remove('flash_message');
$session->clear();          // remove everything

Interface — Bitrix\Main\Session\SessionInterface + ArrayAccess.

Kernel Session (hot)

For a small amount of fast data that the kernel accesses almost every hit:

$kernelSession = Application::getInstance()->getKernelSession();
$kernelSession->set('UF_LAST_LOGIN', time());

In separated mode, the kernel stores the hot fragment in encrypted cookies — making authorization/CSRF fast without accessing backend storage.

SessionLocalStorage — "Session Cache"

Using $session->set(...) for cart cache or temporary calculations is bad: long values block the hit and slow down parallel AJAX. Since main 20.5.400, there is an isolated container tied to session_id():

$local = Application::getInstance()->getLocalSession('cart');

if (!isset($local['productIds']))
{
    $local->set('productIds', [1, 2, 3]);
    $local->set('total', 42);
}

$ids = $local->get('productIds');
  • Stored in the cache from the cache section in .settings.php (not in $_SESSION).
  • Automatically saved at the end of the hit.
  • With file cache, $_SESSION is used internally so that GC correctly cleans up stale data.

Use for: carts, temporary filters, wizards, UI drafts.

Session Modes

Read-only (non-blocking)

Suitable for AJAX where writing is not needed — removes the write lock:

// before including prolog
define('BX_SECURITY_SESSION_READONLY', true);

require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';

After this:

  • Session is read from redis/memcache/db without flock/SETNX — parallel AJAX requests don't wait for each other.
  • Changes will not be saved at the end of the hit.

Good for read-only endpoints (search, suggestions, counters).

Virtual (in-memory)

define('BX_SECURITY_SESSION_VIRTUAL', true);
  • Session is created in memory, not saved at the end of the hit.
  • Used for REST-API with token-based authorization — authorization passes, but the session doesn't clutter storage.

Separated Mode

"Hot" kernel data → cookies, "cold" data → backend storage. Enabled in .settings.php:

'session' => [
    'value' => [
        'mode'     => 'separated',
        'lifetime' => 14400,
        'handlers' => [
            'kernel'  => 'encrypted_cookies',
            'general' => ['type' => 'redis', 'host' => '127.0.0.1', 'port' => 6379],
        ],
    ],
],
  • Fewer calls to Redis/DB.
  • Suitable for high-load: the "hot" part ($_SESSION['BX']) goes to cookies/separate kernel storage, the "cold" part — to the general backend (Redis/DB).

Storages

Specified in /local/.settings.php (or /bitrix/.settings.php) in the session.value.handlers.general.type section:

type When Note
file Dev, small projects Lock by flock → AJAX slows down
redis High-load, clusters Supports servers (cluster/single), serialization
memcache Legacy projects No persistence
database When no cache servers b_user_session table, not for high-load

Redis Cluster Example (multi-master)

'session' => [
    'value' => [
        'mode' => 'default',
        'handlers' => [
            'general' => [
                'type' => 'redis',
                'servers' => [
                    ['host' => '10.0.0.1', 'port' => 6379],
                    ['host' => '10.0.0.2', 'port' => 6379],
                    ['host' => '10.0.0.3', 'port' => 6379],
                ],
                'serializer' => \Redis::SERIALIZER_IGBINARY,
                'persistent' => false,
                'failover'   => \RedisCluster::FAILOVER_DISTRIBUTE,
                'timeout'     => null,
                'readTimeout' => null, // camelCase (session Redis handler)
            ],
        ],
    ],
],

Memcache Cluster Example

'handlers' => [
    'general' => [
        'type' => 'memcache',
        'servers' => [
            ['host' => '10.0.0.1', 'port' => 11211, 'weight' => 1],
            ['host' => '10.0.0.2', 'port' => 11211],
        ],
    ],
],

Database

'handlers' => [
    'general' => ['type' => 'database'], // b_user_session table
],

General Options

'session' => [
    'value' => [
        'lifetime'                 => 14400,  // seconds
        'mode'                     => 'default',
        'regenerateIdAfterLogin'   => true,   // recommended: fixation protection
        'ignoreSessionStartErrors' => false,  // true — hit continues even if Redis is unavailable
        'handlers' => [ ... ],
    ],
],

Flash Messages (common pattern)

$session = Application::getInstance()->getSession();
$session->set('flash.success', 'Post saved');

// next request:
if ($msg = $session->get('flash.success'))
{
    $session->remove('flash.success');
    echo htmlspecialcharsbx($msg);
}

Security

  • After successful login/password change — $session->regenerateId(). Or regenerateIdAfterLogin = true in config.
  • Session cookies should be HttpOnly, Secure, SameSite=Lax|Strict — configured in main module or via session.cookie_* in php.ini. See bitrix-security.
Files (bitrix-framework-skills)
  • SKILL.md 6.1 KB
    ---
    name: bitrix-sessions
    description: Covers Bitrix sessions — Application::getSession(), getKernelSession(), getLocalSession(), BX_SECURITY_SESSION_READONLY and BX_SECURITY_SESSION_VIRTUAL modes, storages (cache, database, redis, null session handler), separated session mode in .settings.php. Applied instead of direct $_SESSION access, when optimizing AJAX session locks, configuring alternative storages, and separating kernel/local sessions. Key terms — session, getSession, session storage, BX_SECURITY_SESSION_READONLY, separated session, getKernelSession, getLocalSession.
    ---
    
    # Bitrix Sessions
    
    Directly accessing `$_SESSION` breaks non-functional modes (`readonly`, virtual session, separated session) and tests. Use the **Session API**.
    
    ```php
    use Bitrix\Main\Application;
    
    $session = Application::getInstance()->getSession();
    
    if (!$session->has('cart'))
    {
        $session->set('cart', ['items' => []]);
    }
    
    $session['cart']['items'][] = $productId;
    $session['cart'] = $cart; // set via ArrayAccess
    
    $session->remove('flash_message');
    $session->clear();          // remove everything
    ```
    
    Interface — `Bitrix\Main\Session\SessionInterface` + `ArrayAccess`.
    
    ## Kernel Session (hot)
    
    For a small amount of fast data that the kernel accesses almost every hit:
    
    ```php
    $kernelSession = Application::getInstance()->getKernelSession();
    $kernelSession->set('UF_LAST_LOGIN', time());
    ```
    
    In `separated` mode, the kernel stores the hot fragment in encrypted cookies — making authorization/CSRF fast without accessing backend storage.
    
    ## SessionLocalStorage — "Session Cache"
    
    Using `$session->set(...)` for cart cache or temporary calculations is bad: long values block the hit and slow down parallel AJAX. Since `main 20.5.400`, there is an isolated container tied to `session_id()`:
    
    ```php
    $local = Application::getInstance()->getLocalSession('cart');
    
    if (!isset($local['productIds']))
    {
        $local->set('productIds', [1, 2, 3]);
        $local->set('total', 42);
    }
    
    $ids = $local->get('productIds');
    ```
    
    - Stored in the cache from the `cache` section in `.settings.php` (not in `$_SESSION`).
    - Automatically saved at the end of the hit.
    - With file cache, `$_SESSION` is used internally so that GC correctly cleans up stale data.
    
    Use for: carts, temporary filters, wizards, UI drafts.
    
    ## Session Modes
    
    ### Read-only (non-blocking)
    
    Suitable for AJAX where writing is not needed — removes the write lock:
    
    ```php
    // before including prolog
    define('BX_SECURITY_SESSION_READONLY', true);
    
    require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
    ```
    
    After this:
    
    - Session is read from redis/memcache/db without `flock`/SETNX — parallel AJAX requests don't wait for each other.
    - Changes **will not be saved** at the end of the hit.
    
    Good for read-only endpoints (search, suggestions, counters).
    
    ### Virtual (in-memory)
    
    ```php
    define('BX_SECURITY_SESSION_VIRTUAL', true);
    ```
    
    - Session is created in memory, not saved at the end of the hit.
    - Used for REST-API with token-based authorization — authorization passes, but the session doesn't clutter storage.
    
    ### Separated Mode
    
    "Hot" kernel data → cookies, "cold" data → backend storage. Enabled in `.settings.php`:
    
    ```php
    'session' => [
        'value' => [
            'mode'     => 'separated',
            'lifetime' => 14400,
            'handlers' => [
                'kernel'  => 'encrypted_cookies',
                'general' => ['type' => 'redis', 'host' => '127.0.0.1', 'port' => 6379],
            ],
        ],
    ],
    ```
    
    - Fewer calls to Redis/DB.
    - Suitable for high-load: the "hot" part (`$_SESSION['BX']`) goes to cookies/separate kernel storage, the "cold" part — to the general backend (Redis/DB).
    
    ## Storages
    
    Specified in `/local/.settings.php` (or `/bitrix/.settings.php`) in the `session.value.handlers.general.type` section:
    
    | type | When | Note |
    | --- | --- | --- |
    | `file` | Dev, small projects | Lock by `flock` → AJAX slows down |
    | `redis` | High-load, clusters | Supports `servers` (cluster/single), serialization |
    | `memcache` | Legacy projects | No persistence |
    | `database` | When no cache servers | `b_user_session` table, not for high-load |
    
    ### Redis Cluster Example (multi-master)
    
    ```php
    'session' => [
        'value' => [
            'mode' => 'default',
            'handlers' => [
                'general' => [
                    'type' => 'redis',
                    'servers' => [
                        ['host' => '10.0.0.1', 'port' => 6379],
                        ['host' => '10.0.0.2', 'port' => 6379],
                        ['host' => '10.0.0.3', 'port' => 6379],
                    ],
                    'serializer' => \Redis::SERIALIZER_IGBINARY,
                    'persistent' => false,
                    'failover'   => \RedisCluster::FAILOVER_DISTRIBUTE,
                    'timeout'     => null,
                    'readTimeout' => null, // camelCase (session Redis handler)
                ],
            ],
        ],
    ],
    ```
    
    ### Memcache Cluster Example
    
    ```php
    'handlers' => [
        'general' => [
            'type' => 'memcache',
            'servers' => [
                ['host' => '10.0.0.1', 'port' => 11211, 'weight' => 1],
                ['host' => '10.0.0.2', 'port' => 11211],
            ],
        ],
    ],
    ```
    
    ### Database
    
    ```php
    'handlers' => [
        'general' => ['type' => 'database'], // b_user_session table
    ],
    ```
    
    ## General Options
    
    ```php
    'session' => [
        'value' => [
            'lifetime'                 => 14400,  // seconds
            'mode'                     => 'default',
            'regenerateIdAfterLogin'   => true,   // recommended: fixation protection
            'ignoreSessionStartErrors' => false,  // true — hit continues even if Redis is unavailable
            'handlers' => [ ... ],
        ],
    ],
    ```
    
    ## Flash Messages (common pattern)
    
    ```php
    $session = Application::getInstance()->getSession();
    $session->set('flash.success', 'Post saved');
    
    // next request:
    if ($msg = $session->get('flash.success'))
    {
        $session->remove('flash.success');
        echo htmlspecialcharsbx($msg);
    }
    ```
    
    ## Security
    
    - After successful login/password change — `$session->regenerateId()`. Or `regenerateIdAfterLogin = true` in config.
    - Session cookies should be `HttpOnly`, `Secure`, `SameSite=Lax|Strict` — configured in main module or via `session.cookie_*` in php.ini. See `bitrix-security`.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related