MonkeysLegion Entity is a lightweight, attribute-based data-mapper and entity scanner for PHP 8.4+. It provides a clean way to map database rows to PHP objects using attributes, scan directories for entities, and implement class-specific observers for lifecycle events.
- Attribute-based Mapping: Define entities and their fields using PHP 8.4+ attributes.
- Flexible Hydration: Map database rows to entities and extract data back for persistence with ease.
- Entity Scanner: Automatically discover entity classes in your project.
- UUID Support: Integrated UUID v4 generator and attribute for primary keys.
- Class-Specific Observers: Hook into entity lifecycle events (creating, updating, saving, deleting, hydrated) with dedicated observer classes.
- Easy Integration: Designed to be used with any repository or data-manager implementation.
composer require monkeyscloud/monkeyslegion-entityMark your class with the #[Entity] attribute and use #[Column] or #[Field] for its properties.
use MonkeysLegion\Entity\Attributes\Entity;
use MonkeysLegion\Entity\Attributes\Column;
use MonkeysLegion\Entity\Attributes\Id;
#[Entity(table: 'users')]
class User
{
#[Id]
#[Column]
private int $id;
#[Column]
private string $username;
#[Column]
private string $email;
// Getters and setters...
}You can mark properties as UUIDs using the #[Uuid] attribute. This is particularly useful for primary keys that should be generated as UUIDs.
use MonkeysLegion\Entity\Attributes\Entity;
use MonkeysLegion\Entity\Attributes\Id;
use MonkeysLegion\Entity\Attributes\Uuid;
use MonkeysLegion\Entity\Utils\Uuid as UuidUtil;
#[Entity(table: 'profiles')]
class Profile
{
#[Id]
#[Uuid]
private string $id;
public function __construct()
{
// You can use the built-in utility to generate a UUID v4
$this->id = UuidUtil::v4();
}
}You can attach an observer to an entity class using the #[ObservedBy] attribute.
Extend the EntityObserver base class and override the methods you need.
use MonkeysLegion\Entity\Observers\EntityObserver;
class UserObserver extends EntityObserver
{
public function creating(object $entity): void
{
// Set default values or hash passwords
echo "Creating user: " . $entity->getUsername();
}
public function hydrated(object $entity): void
{
// Perform actions after the entity is loaded from the database
echo "User hydrated!";
}
}You can register a single observer or an array of observers:
use MonkeysLegion\Entity\Attributes\Entity;
use MonkeysLegion\Entity\Attributes\ObservedBy;
#[Entity(table: 'users')]
#[ObservedBy(UserObserver::class)] // Single observer
class User
{
// ...
}
#[Entity(table: 'posts')]
#[ObservedBy([PostObserver::class, ActivityLogObserver::class])] // Multiple observers
class Post
{
// ...
}creating/created: Before and after an insert operation.updating/updated: Before and after an update operation.saving/saved: Before and after both insert and update operations.deleting/deleted: Before and after a delete operation.hydrated: After an entity is populated from a database row.
Use EntityScanner to find all classes marked with the #[Entity] attribute in a directory.
use MonkeysLegion\Entity\Scanner\EntityScanner;
$scanner = new EntityScanner();
$entities = $scanner->scanDir(__DIR__ . '/src/Entities');
foreach ($entities as $reflectionClass) {
echo "Found entity: " . $reflectionClass->getName() . "\n";
}The Hydrator class handles the conversion between database rows (arrays/objects) and entities.
use MonkeysLegion\Entity\Hydrator;
// From DB to Entity
$user = Hydrator::hydrate(User::class, $dbRow);
// From Entity to DB data
$data = Hydrator::extract($user);This project is licensed under the MIT License - see the LICENSE file for details.