The VirtualEntity class provides a dynamic entity container that allows you to define, read, and modify object-like properties without explicitly declaring them.
It works like a lightweight data value object (DVO) or entity proxy, supporting:
getName(), setName($value)).$entity['name']).get or set).Krystal\Security\Filter.This class is particularly useful when dealing with flexible or dynamic data structures, where property names may not be known at compile time.
<?php
use Krystal\Stdlib\VirtualEntity;
$entity = new VirtualEntity();
// Set virtual properties
$entity->setName('Alice');
$entity->setEmail('alice@example.com');
// Get virtual properties
echo $entity->getName(); // Output: Alice
echo $entity->getEmail(); // Output: alice@example.com
$entity = new VirtualEntity();
$entity['name'] = 'Bob';
echo $entity['name']; // Output: Bob
unset($entity['name']);
var_dump(isset($entity['name'])); // false
This example demonstrates the write-once mode controlled by the $once constructor argument.
When $once = true, each property in the VirtualEntity can be assigned only once. If you try to set the same property again, the class throws a RuntimeException.
This is useful when you want to make entity data immutable after initialization, ensuring that once a value is written, it cannot be accidentally overwritten later in the code — for example, in configuration objects, request data, or entities that should remain stable after creation.
$entity = new VirtualEntity($once = true);
$entity->setUsername('first');
// The next line throws RuntimeException because write-once mode is active
$entity->setUsername('second');
When enabled ($strict = true), it ensures that all dynamic method calls must begin with either get or set.
This helps catch typos and logic errors early — for example, calling $entity->fetchName() would throw an exception instead of silently doing nothing.
Use strict mode when you want your entities to behave predictably and fail fast if someone tries to call an invalid or misspelled virtual method.
$entity = new VirtualEntity($once = false, $strict = true);
// This will throw a RuntimeException because "fetchName" is not allowed
$entity->fetchName();
Sanitization helps ensure that data stored in entities is safe and consistent, especially when it originates from user input.
By combining VirtualEntity with Sanitizeable filters, you can protect your application from XSS attacks, data corruption, and unexpected type issues — all while keeping your code clean and declarative.
VirtualEntity can sanitize property values automatically when calling a setter.
<?php
use Krystal\Stdlib\VirtualEntity;
use Krystal\Security\Sanitizeable;
$entity = new VirtualEntity();
// Set a value with HTML tags, sanitized using a defined filter
$entity->setComment('<b>Hello</b>', Sanitizeable::FILTER_HTML);
echo $entity->getComment();
// Output: Hello (HTML removed)
You can pass a second argument to a set*() method that specifies which filter to apply, using one of the constants from Krystal\Security\Sanitizeable.
| Constant | Description |
|---|---|
Sanitizeable::FILTER_NONE |
No filtering (value remains unchanged). |
Sanitizeable::FILTER_FLOAT |
Converts value to a floating-point number. |
Sanitizeable::FILTER_INT |
Converts value to an integer. |
Sanitizeable::FILTER_BOOL |
Converts value to a boolean. |
Sanitizeable::FILTER_HTML |
Removes HTML markup entirely. |
Sanitizeable::FILTER_TAGS |
Strips all HTML and PHP tags. |
Sanitizeable::FILTER_SAFE_TAGS |
Allows only safe HTML tags (like <b>, <i>, etc.). |
Sanitizeable::FILTER_HTML_CHARS |
Escapes HTML characters (e.g., < becomes <). |
$entity = new VirtualEntity();
$entity->setName('Alice');
$entity->setRole('Admin');
print_r($entity->getProperties());
This will output
Array
(
[name] => Alice
[role] => Admin
)