JSON Columns
Miko ORM provides support for JSON columns with dot notation access. Store and manipulate JSON data directly in your database columns.
JSON Column Methods Summary
| Method | Description |
|---|---|
getJson($column, $key) | Get value from JSON column |
setJson($column, $key, $value) | Set value in JSON column |
appendJson($column, $key, $value) | Append to array in JSON |
removeJson($column, $key) | Remove key from JSON |
hasJson($column, $key) | Check if key exists |
incrementJson($column, $key) | Increment numeric value |
decrementJson($column, $key) | Decrement numeric value |
Using JsonColumnTrait
Add the trait to your model to enable JSON column support.
use Miko\Database\ORM\Model;
use Miko\Database\ORM\JsonColumnTrait;
class User extends Model
{
use JsonColumnTrait;
// Define which columns contain JSON data
protected array $jsonColumns = ['settings', 'metadata', 'preferences'];
}
Setting JSON Values
Set Entire JSON Object
$user = User::find(1);
// Set entire JSON column
$user->setJson('settings', [
'theme' => 'dark',
'language' => 'en',
'notifications' => [
'email' => true,
'push' => false
]
]);
$user->save();
Set Specific Key
// Set single key
$user->setJson('settings', 'theme', 'light');
// Set nested key with dot notation
$user->setJson('settings', 'notifications.email', false);
$user->setJson('settings', 'notifications.sms', true);
$user->save();
Set Deep Nested Values
// Create deep nested structure
$user->setJson('metadata', 'social.twitter.username', '@johndoe');
$user->setJson('metadata', 'social.twitter.followers', 1500);
$user->setJson('metadata', 'social.linkedin.url', 'linkedin.com/in/johndoe');
$user->save();
// Result:
// {
// "social": {
// "twitter": { "username": "@johndoe", "followers": 1500 },
// "linkedin": { "url": "linkedin.com/in/johndoe" }
// }
// }
Getting JSON Values
Get Entire JSON
$user = User::find(1);
// Get entire JSON as array
$settings = $user->getJson('settings');
print_r($settings);
// Array ( [theme] => dark, [language] => en, ... )
Get Specific Key
// Get single key
$theme = $user->getJson('settings', 'theme');
echo $theme; // "dark"
// Get nested key with dot notation
$emailNotif = $user->getJson('settings', 'notifications.email');
echo $emailNotif; // true
Get with Default Value
// Returns default if key doesn't exist
$timezone = $user->getJson('settings', 'timezone', 'UTC');
$currency = $user->getJson('preferences', 'currency', 'USD');
Array Operations
Append to Array
// Append single value
$user->appendJson('settings', 'tags', 'vip');
$user->appendJson('settings', 'tags', 'premium');
// Result: { "tags": ["vip", "premium"] }
// Append to nested array
$user->appendJson('metadata', 'history.logins', date('Y-m-d H:i:s'));
Remove from JSON
// Remove key
$user->removeJson('settings', 'deprecated_option');
// Remove nested key
$user->removeJson('metadata', 'social.twitter');
$user->save();
Numeric Operations
Increment
// Increment by 1
$user->incrementJson('metadata', 'login_count');
// Increment by specific amount
$user->incrementJson('metadata', 'points', 50);
// Increment nested value
$user->incrementJson('stats', 'visits.total', 1);
$user->save();
Decrement
// Decrement by 1
$user->decrementJson('metadata', 'credits');
// Decrement by specific amount
$user->decrementJson('metadata', 'balance', 25.50);
$user->save();
Check Key Existence
// Check if key exists
if ($user->hasJson('settings', 'theme')) {
echo "Theme is set";
}
// Check nested key
if ($user->hasJson('metadata', 'social.twitter')) {
echo "Twitter connected";
}
JsonDictionary Class
A standalone class for working with JSON key-value data.
use Miko\Database\ORM\JsonDictionary;
// Create from array
$dict = new JsonDictionary([
'name' => 'John',
'age' => 30
]);
// Create from JSON string
$dict = new JsonDictionary('{"name":"John","age":30}');
// Set values
$dict->set('email', 'john@example.com');
$dict['phone'] = '555-1234'; // Array access
// Get values
echo $dict->get('name'); // "John"
echo $dict['age']; // 30
echo $dict->get('missing', 'default'); // "default"
// Check existence
if ($dict->has('email')) {
echo "Has email";
}
// Remove
$dict->remove('phone');
// Convert
$array = $dict->toArray();
$json = $dict->toJson();
// Iterate
foreach ($dict as $key => $value) {
echo "$key: $value\n";
}
// Count
echo count($dict); // 3
JsonList Class
A standalone class for working with JSON arrays.
use Miko\Database\ORM\JsonList;
// Create from array
$list = new JsonList(['apple', 'banana', 'orange']);
// Create from JSON string
$list = new JsonList('["apple","banana","orange"]');
// Add items
$list->add('grape');
$list->addRange(['mango', 'kiwi']);
$list[] = 'pear'; // Array access
// Get items
echo $list->get(0); // "apple"
echo $list[1]; // "banana"
echo $list->first(); // "apple"
echo $list->last(); // "pear"
// Check & Find
if ($list->contains('banana')) {
echo "Has banana";
}
$index = $list->indexOf('orange'); // 2
// Remove
$list->remove('banana'); // Remove by value
$list->removeAt(0); // Remove by index
// Clear
$list->clear();
// Convert
$array = $list->toArray();
$json = $list->toJson();
// Iterate
foreach ($list as $item) {
echo $item . "\n";
}
// Count
echo count($list);
Practical Examples
User Settings
class User extends Model
{
use JsonColumnTrait;
protected array $jsonColumns = ['settings'];
// Helper methods
public function getTheme(): string
{
return $this->getJson('settings', 'theme', 'light');
}
public function setTheme(string $theme): void
{
$this->setJson('settings', 'theme', $theme);
}
public function isNotificationEnabled(string $type): bool
{
return $this->getJson('settings', "notifications.$type", true);
}
public function toggleNotification(string $type): void
{
$current = $this->isNotificationEnabled($type);
$this->setJson('settings', "notifications.$type", !$current);
}
}
// Usage
$user = User::find(1);
$user->setTheme('dark');
$user->toggleNotification('email');
$user->save();
Product Attributes
class Product extends Model
{
use JsonColumnTrait;
protected array $jsonColumns = ['attributes', 'specifications'];
public function getAttribute(string $key, $default = null)
{
return $this->getJson('attributes', $key, $default);
}
public function setAttributes(array $attributes): void
{
foreach ($attributes as $key => $value) {
$this->setJson('attributes', $key, $value);
}
}
}
// Usage
$product = Product::find(1);
$product->setAttributes([
'color' => 'red',
'size' => 'large',
'weight' => 2.5
]);
$product->setJson('specifications', 'dimensions', [
'width' => 10,
'height' => 20,
'depth' => 5
]);
$product->save();
echo $product->getAttribute('color'); // "red"
Activity Log
class User extends Model
{
use JsonColumnTrait;
protected array $jsonColumns = ['activity_log'];
public function logActivity(string $action, array $data = []): void
{
$entry = [
'action' => $action,
'data' => $data,
'timestamp' => date('Y-m-d H:i:s'),
'ip' => $_SERVER['REMOTE_ADDR'] ?? null
];
$this->appendJson('activity_log', 'entries', $entry);
$this->incrementJson('activity_log', 'total_actions');
$this->save();
}
public function getRecentActivity(int $limit = 10): array
{
$entries = $this->getJson('activity_log', 'entries', []);
return array_slice(array_reverse($entries), 0, $limit);
}
}
// Usage
$user = User::find(1);
$user->logActivity('login', ['browser' => 'Chrome']);
$user->logActivity('view_product', ['product_id' => 123]);
$recent = $user->getRecentActivity(5);