About bitrix-storage
A storage-selection guide for Bitrix PHP developers, covering module options, feature flags, and expiring persistent data. It also describes when to use cache, sessions, and files, along with API constraints.
Key features
- 01Module options and defaults
- 02Feature flags with user rules
- 03Persistent storage with TTL
- 04Choosing storage by use case
- 05Deferred writes and cache handling
Use cases
- 01Store module settings editable by administrators
- 02Roll out a feature to selected users
- 03Keep task state for a limited time
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ bxmaximum/ bitrix-framework-skills --skill bitrix-storageAfter installing, type/bitrix-storagein Claude Code to confirm it loaded.
Details
From the project READMEStorage: Option, Feature, Persistent storage
Baseline: main 23.0+ · Verified: main 26.800.0
| Need | Use |
|---|---|
| Deploy-time config, secrets | .settings_extra.php / env (bitrix-settings) |
| Permanent admin-editable module setting | Config\Option + default_option.php |
| Feature toggle, gradual rollout per user | Config\Feature (Since main 26.700); older: Option Y/N |
| Server state that must live N seconds | PersistentStorageInterface (Since main 25.1100); older: own ORM table with an expiry column |
| Derived data, may vanish anytime | cache (bitrix-caching) |
| Per-visitor state | session (bitrix-sessions) |
| Large blobs | files (bitrix-files) |
Don't use Option for chatty runtime state (progress, tokens, checkpoints), cache for data that must survive, or Persistent storage for secrets.
Option
use Bitrix\Main\Config\Option;
$interval = (int)Option::get('vendor.module', 'sync_interval'); // falls back to default_option.php
Option::set('vendor.module', 'sync_interval', (string)$interval);
$stored = Option::getRealValue('vendor.module', 'sync_interval'); // null if never stored
$all = Option::getForModule('vendor.module');
Option::delete('vendor.module', ['name' => 'sync_interval']); // no filter = all module options
- Values are strings; cast at the boundary. Defaults:
bitrix-modules(default_option.php). - Site override: pass
$siteId; empty site = global. set()clears the options cache, runsoption_triggers.php, firesOnAfterSetOption_<name>/OnAfterSetOption— not for per-hit writes.- Distinguish "unset" from default:
getRealValue()or a sentinel default (Option::get('main', 'x', 'Z')).
Feature flags — Since main 26.700
A flag is a class in your module's lib/ (the module is derived from the namespace: Vendor\Shop\… → vendor.shop):
namespace Vendor\Shop\Config\Feature;
use Bitrix\Main\Config\Feature\AbstractFlag;
use Bitrix\Main\Config\Feature\Context;
final class NewCheckoutFlag extends AbstractFlag
{
public function enabledByDefault(): bool
{
return false;
}
public function getRequirements(): array
{
return [static fn (Context $context): bool => $context->userId !== null]; // all must pass
}
}
use Bitrix\Main\Config\Feature;
use Bitrix\Main\Config\Feature\Rules\UserIdRule;
if (Feature::isEnabled(NewCheckoutFlag::class)) { /* new flow */ }
Feature::allow(NewCheckoutFlag::class, UserIdRule::class, ['userIds' => [1, 42]]); // beta users
Feature::enable(NewCheckoutFlag::class); // everyone; stored in b_feature_flag
Feature::resetToDefault(NewCheckoutFlag::class); // rules stay: clearRules()
- Decision order: requirements →
denyrules →allowrules → stored value →enabledByDefault(). - Rules:
UserIdRule(userIds),ModuleMinVersionRule(module,minVersion); own rule extendsAbstractRule(static createFromConfig(array $config),check(Context $context): bool). - Context: current user by default;
new Context(?int $userId = null, array $params = []), IDs < 1 = anonymous. - Pitfalls: an unknown/unloadable flag class returns true ("shipped and removed");
enable()/disable()silently do nothing if the namespace's module is not installed — never define flags inphp_interface. Values and rules are cached 24 h; after direct table edits callFeature::clearCache().onEnable()/onDisable()fire only on a real stored change.
Persistent storage — Since main 25.1100
$storage = \Bitrix\Main\DI\ServiceLocator::getInstance()
->get(\Bitrix\Main\Data\Storage\PersistentStorageInterface::class);
$storage->set('vendor.module.import.42', ['step' => 3], 3600); // TTL required
$state = $storage->get('vendor.module.import.42'); // null after expiry
$storage->delete('vendor.module.import.42');
- PSR-16 API; DB-backed (
ConnectionBasedPersistentStorage). Key ≤ 255 chars (module.feature.id), JSON-serializable value. - TTL: positive
intseconds orDateInterval;null/≤ 0→InvalidTtlException. Keep ≤ 7 days.clear()is not supported. new DeferredStorageDecorator($storage)buffers writes untilsave()or destruction — many writes per hit, loss on crash acceptable.
Comments
Markdown supported