User Preference¶
Nene\Kit\UserPreference — user preference key-value store with default-value fallback and type casting.
Schema¶
CREATE TABLE user_preferences (
user_id VARCHAR(255) NOT NULL,
pref_key VARCHAR(255) NOT NULL,
pref_value TEXT NOT NULL,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, pref_key)
);
The composite primary key (user_id, pref_key) ensures one value per user per key. pref_value is always stored as a string; type conversion happens at the application layer.
API¶
| Method | Description |
|---|---|
get(string $userId, string $key, ?string $default = null): ?string |
Get preference as string, or $default if not set. |
getInt(string $userId, string $key, int $default = 0): int |
Get preference cast to int. |
getBool(string $userId, string $key, bool $default = false): bool |
Get preference cast to bool. |
set(string $userId, string $key, string $value): void |
Create or overwrite a preference. |
delete(string $userId, string $key): bool |
Remove a preference. Returns true if deleted. |
all(string $userId): array<string, string> |
Get all preferences as a key→value map. |
Usage¶
$prefs = new UserPreference($pdo);
// Set
$prefs->set('user:1', 'theme', 'dark');
$prefs->set('user:1', 'items_per_page', '20');
$prefs->set('user:1', 'notifications', '1');
// Get with default fallback
$prefs->get('user:1', 'theme', 'light'); // 'dark' (stored)
$prefs->get('user:1', 'language', 'ja'); // 'ja' (default — not stored)
// Type casting
$prefs->getInt('user:1', 'items_per_page', 10); // 20
$prefs->getBool('user:1', 'notifications', false); // true
// Overwrite
$prefs->set('user:1', 'theme', 'light');
$prefs->get('user:1', 'theme'); // 'light'
// Delete (revert to default)
$prefs->delete('user:1', 'theme'); // true
$prefs->get('user:1', 'theme', 'light'); // 'light' (default)
// All preferences
$prefs->all('user:1');
// ['items_per_page' => '20', 'notifications' => '1']
Boolean storage conventions¶
getBool() returns true for values '1', 'true', 'yes' (case-insensitive) and false for everything else.
Store booleans as '1' or '0' for consistency:
$prefs->set('user:1', 'dark_mode', $isDark ? '1' : '0');
$prefs->getBool('user:1', 'dark_mode'); // true or false
Key design points¶
- String storage: all values stored as
TEXT; no type coercion in DB. - Upsert:
set()usesINSERT OR REPLACE(SQLite) /INSERT … ON DUPLICATE KEY UPDATE(MySQL). - Delete = revert to default: removing a key causes
get()to return the provided default. - User isolation: all queries are scoped by
user_id. - PDO injection:
__construct(private readonly ?PDO $db = null).