cakephp/orm
Standalone CakePHP ORM package providing table/association mapping, entities, query builder, validation and eager loading. Use Cake’s database layer outside full CakePHP apps, with expressive queries and flexible data access patterns.
Installation
composer require cakephp/orm
Add to composer.json under autoload-dev (if using for testing) or autoload:
"autoload": {
"psr-4": {
"App\\": "app/",
"Cake\\": "vendor/cakephp/orm/src/"
}
}
Run composer dump-autoload.
First Use Case: Querying a Database Table
Define a Table class (e.g., app/Database/UsersTable.php):
namespace App\Database;
use Cake\ORM\Table;
use Cake\ORM\RulesChecker;
class UsersTable extends Table
{
protected function _initializeSchema()
{
return [
'users' => [
'id' => ['type' => 'integer'],
'name' => ['type' => 'string', 'null' => false],
'email' => ['type' => 'string', 'null' => false]
]
];
}
}
Query users in a Laravel controller:
use App\Database\UsersTable;
$usersTable = new UsersTable();
$users = $usersTable->find()->all();
Entity class for model objects (e.g., Cake\ORM\Entity).
$user = $usersTable->newEntity(['name' => 'John', 'email' => 'john@example.com']);
$usersTable->save($user);
initialize():
protected function _initialize(Connection $connection)
{
$this->hasMany('Posts', ['foreignKey' => 'user_id']);
}
// Find by ID
$user = $usersTable->get(1);
// Where clause
$activeUsers = $usersTable->find()->where(['active' => true]);
// Ordering/Limiting
$users = $usersTable->find()->order(['name' => 'ASC'])->limit(10);
$usersWithPosts = $usersTable->find()
->contain(['Posts'])
->where(['Posts.title LIKE' => '%test%']);
initialize():
protected function _initialize(Connection $connection)
{
$this->addBehavior('Timestamp');
$this->validationDefault = [
'email' => ['rule' => 'email']
];
}
if (!$user->errors()) {
$usersTable->save($user);
}
$connection = $usersTable->getConnection();
$connection->begin();
try {
$usersTable->save($user);
$postsTable->save($post);
$connection->commit();
} catch (\Exception $e) {
$connection->rollBack();
}
Create a Laravel service provider to bind CakePHP tables:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Database\UsersTable;
class CakePHPServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton('usersTable', function ($app) {
return new UsersTable();
});
}
}
Register in config/app.php:
'providers' => [
App\Providers\CakePHPServiceProvider::class,
],
config/database.php:
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'prefix' => '',
],
],
$queryLogger = new \Cake\Log\Engine\FileEngine([
'path' => storage_path('logs/cake_queries.log'),
'levels' => ['query'],
]);
\Cake\Log\Log::config('query', $queryLogger);
debug() to inspect queries:
$query = $usersTable->find()->where(['active' => true]);
\Cake\Log\Log::debug($query->sql());
N+1 queries by using contain():
// Bad (N+1)
foreach ($users as $user) {
$user->posts; // Triggers a query per user
}
// Good
$users = $usersTable->find()->contain(['Posts'])->all();
newEntity() or patchEntity():
$user = $usersTable->patchEntity($existingUser, ['name' => 'Updated']);
Cake\ORM\Query for reusable logic:
namespace App\ORM;
use Cake\ORM\Query;
class CustomQuery extends Query
{
public function active()
{
return $this->where(['active' => true]);
}
}
Use in a table:
$activeUsers = $usersTable->find('custom', ['type' => 'active']);
Cake\ORM\Behavior\Timestamp):
$this->addBehavior('Timestamp');
Model.beforeSave):
$this->addEventListener('Model.beforeSave', function ($event, $entity, $options) {
$entity->slug = Str::slug($entity->name);
});
saveMany() for bulk inserts/updates:
$usersTable->saveMany([
$user1, $user2, $user3
]);
$cacheKey = 'users_active';
$users = \Cache::remember($cacheKey, 60, function () use ($usersTable) {
return $usersTable->find()->where(['active' => true])->all();
});
How can I help you explore Laravel packages today?