A lightweight Object-Relational Mapper (ORM) for PHP 8.1+, focusing on simplicity, naming conventions, and built-in migration support.
- Reflection-based Mapping: Automatic property-to-column mapping.
- Support for Private Properties: Clean encapsulation with full access for the ORM.
- Attribute-based Metadata: Fine-grained control with
#[Id],#[Column], and#[Sensitive]. - Integrated Migrations: Automatic schema extraction and SQL generation (Up/Down support).
- Type Validation: Built-in validation including support for numeric strings from databases.
Entities should extend BaseEntity. Use attributes to define your schema.
useOrm\Entity\BaseEntity;
useOrm\Attribute\Id;
useOrm\Attribute\Column;
useOrm\Attribute\Sensitive;
class UserEntity extends BaseEntity
{
#[Id]
privateint$id;
#[Column(unique: true)]
privatestring$username;
#[Column(name: 'email_address')]
privatestring$email;
#[Sensitive]
privatestring$password;
// Getters and setters are supported but optional for the ORMpublicfunctiongetId(): int { return$this->id; }
publicfunctiongetUsername(): string { return$this->username; }
}Note: Table names are automatically pluralized (e.g., UserEntity -> userentities or User -> users). Use the naming convention [Name]Entity or just [Name].
Repositories handle database operations.
useOrm\Repository\BaseRepository;
class UserRepository extends BaseRepository {
// Custom query methods can be added here
}$pdo = newPDO('sqlite:db.sqlite');
$repo = newUserRepository($pdo);
// Create$user = newUserEntity();
$user->fromArray([
'username' => 'johndoe',
'email_address' => 'john@example.com',
'password' => 'secret123'
]);
$repo->create($user);
// Find$foundUser = $repo->findById($user->getId());
// Update$foundUser->fromArray(['username' => 'john_fixed']);
$repo->update($foundUser);
// Delete$repo->delete($foundUser->getId());
// Find All$allUsers = $repo->findAll(limit: 10, offset: 0); // Returns EntityCollectionThe ORM can automatically manage your database schema.
# Initialize the schema (creates initial SQL and snapshot)
php bin/migrate.php init
# After changing your Entities, create a new migration
php bin/migrate.php create
# Run pending migrations
php bin/migrate.php up
# Revert migrations
php bin/migrate.php down --to=20231027_120000
# Check status
php bin/migrate.php statusAdd these to your composer.json for easier access:
{
"scripts": {
"migrate": "php bin/migrate.php",
"create-entity": "php bin/create.php entity"
}
}composer require looserouting/orm