This cookbook entry describes how to use the Atlas 3 ORM and its command-line tooling with Slim.
Install Atlas using Composer. The ORM and CLI packages are delivered separately, since you are likely to need the command line tooling only in development:
composer require atlas/orm ~3.0
composer require --dev atlas/cli ~2.0
Note:
If you are using PHPStorm, you may wish to copy the IDE meta file to your project to get full autocompletion on Atlas classes:
cp ./vendor/atlas/orm/resources/phpstorm.meta.php ./.phpstorm.meta.php
Now you need to add some database connection settings to your configuration.
You can add them under any array key you like; the following example uses
['settings']['atlas']
:
<?php
// ./config/settings.php
return [
'settings' => [
'displayErrorDetails' => true,
'determineRouteBeforeAppMiddleware' => false,
'atlas' => [
'pdo' => [
'mysql:dbname=testdb;host=localhost',
'username',
'password',
],
'namespace' => 'DataSource',
'directory' => dirname(__DIR__) . '/src/classes/DataSource',
]
]
];
The pdo
elements are used as arguments for your
PDO connection.
The namespace
and directory
elements specify the namespace for your Atlas
data source classes, and the directory where they will be saved by the skeleton
generator. Your composer.json
will need have a PSR autoloader entry for these;
the above example corresponds to the Slim
tutorial application.
Now you can generate your skeleton data source classes with the Atlas CLI tooling. First, create the target directory, then issue the skeleton command:
mkdir -p ./src/classes/DataSource
php ./vendor/bin/atlas-skeleton.php ./config/settings.php settings.atlas
The first argument to atlas-skeleton
is the path to your Slim config file. The
second argument is a dot-separated list of the keys leading to the Atlas array
within the settings.
With that command, Atlas will examine your database and generate a series of classes and traits for each table in the schema. You can see the files generated for each table here.
With the data mapper classes in place, you can now add the Atlas ORM as a service in the Slim container:
<?php
$container = $app->getContainer();
$container['atlas'] = function ($container) {
$args = $container['settings']['atlas']['pdo'];
$atlasBuilder = new AtlasBuilder(...$args);
$atlasBuilder->setFactory(function ($class) use ($container) {
if ($container->has($class)) {
return $container->get($class);
}
return new $class();
});
return $atlasBuilder->newAtlas();
};
This uses the AtlasBuilder class to create and return a new ORM instance, with the PDO connection arguments from your settings configuration.
Note:
This service definition tells Atlas to use the Container itself as a factory for certain class constructions. If you have Atlas TableEvent or MapperEvent classes defined as services in the Container, Atlas will use the Container to build them for you.
At this point, you can use the full power of the Atlas ORM in your action code. The following examples are adapted from the tutorial application:
<?php
use DataSource\Ticket\Ticket;
use DataSource\Component\Component;
$app->get('/tickets', function (Request $request, Response $response) {
$this->logger->addInfo("Ticket list");
$tickets = $this->atlas->select(Ticket::class)->fetchRecordSet();
$response = $this->view->render(
$response,
"tickets.phtml",
[
"tickets" => $tickets,
"router" => $this->router
]
);
return $response;
});
$app->get('/ticket/{id}', function (Request $request, Response $response, $args) {
$ticket_id = (int) $args['id'];
$ticket = $this->atlas->fetchRecord(Ticket::class, $ticket_id);
$response = $this->view->render(
$response,
"ticketdetail.phtml",
[
"ticket" => $ticket
]
);
return $response;
})->setName('ticket-detail');
$app->post('/ticket/new', function (Request $request, Response $response) {
$data = $request->getParsedBody();
$ticket = $this->atlas->newRecord(Ticket::class);
$ticket->title = filter_var($data['title'], FILTER_SANITIZE_STRING);
$ticket->description = filter_var($data['description'], FILTER_SANITIZE_STRING);
$component_id = (int) $data['component'];
$component = $this->atlas->fetchRecord(Component::class, $component_id)
$ticket->component = $component->getName();
$this->atlas->persist($ticket);
$response = $response->withRedirect("/tickets");
return $response;
});
That’s it!
For more information on how to use Atlas to its greatest extent, be sure to read the official documentation:
Working with Records and RecordSets
Other topics such as custom mapper methods, single table inheritance, many-to-many relationships, and automated validation
Enjoy!