Using preInsert event for generating UUID with laminas-db
If you want to do something before insert data into database table, for example: generate id as UUID binary, you can do with preInsert
event. For example, you have the following album
table structure:
DROP TABLE IF EXISTS `album`; CREATE TABLE `album` ( `id` binary(16) NOT NULL COMMENT 'uuid binary', `artist` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; ALTER TABLE `album` ADD PRIMARY KEY (`id`);
Now, to generate the UUID data, you can use ramsey/uuid
, you can require:
➜ composer require ramsey/uuid
Now, time for the action!
Note, this is just a quick example to show you how it works. You can borrow your design architecture you love in real implementation.
For example, in laminas-mvc-skeleton application, we inject the IndexController with db adapter via factory:
namespace Application\Controller; use Laminas\Db\Adapter\AdapterInterface; class IndexControllerFactory { public function __invoke($c) { return new IndexController($c->get(AdapterInterface::class)); } }
Now, we can update the module/Application/config/module.config.php
controller factory:
// ... 'controllers' => [ 'factories' => [ Controller\IndexController::class => Controller\IndexControllerFactory::class, ], ], // ...
In our IndexController __construct, we can use the db adapter to create the TableGateway instance featuring EventFeature:
<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\TableGateway\Feature\EventFeature; use Laminas\Db\TableGateway\Feature\EventFeature\TableGatewayEvent; use Laminas\Db\TableGateway\Feature\EventFeatureEventsInterface; use Laminas\Db\TableGateway\TableGateway; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; use Ramsey\Uuid\Uuid; class IndexController extends AbstractActionController { private $albumTableGateway; public function __construct(AdapterInterface $adapter) { $events = $this->getEventManager(); $events->attach(EventFeatureEventsInterface::EVENT_PRE_INSERT, function (TableGatewayEvent $event) { $insert = $event->getParam('insert'); $insert->id = Uuid::uuid4()->getBytes(); }); $this->albumTableGateway = new TableGateway('album', $adapter, new EventFeature($events)); } }
Above, with EventFeatureEventsInterface::EVENT_PRE_INSERT
, we update the insert id with the binary value generated.
Let’s check with index action for insert:
// ... public function indexAction() { $this->albumTableGateway->insert([ 'artist' => 'Sheila on 7', 'title' => 'Pejantan Tangguh', ]); return new ViewModel(); } // ..
Ok, when open the index page, we will have the album table inserted with id generated in preInsert event.
mysql> SELECT LOWER( -> CONCAT(SUBSTR(HEX(id), 1, 8) -> , '-' -> , SUBSTR(HEX(id), 9, 4) -> , '-' -> , SUBSTR(HEX(id), 13, 4) -> , '-' -> , SUBSTR(HEX(id), 17, 4) -> , '-' -> , SUBSTR(HEX(id), 21)) -> ) as id, -> artist, -> title -> FROM album; +--------------------------------------+-------------+------------------+ | id | artist | title | +--------------------------------------+-------------+------------------+ | 551a8518-cdd2-4f3a-968d-a45a4b232b5e | Sheila on 7 | Pejantan Tangguh | +--------------------------------------+-------------+------------------+ 1 row in set (0.00 sec)
For complete event list, you can read the documentation https://docs.laminas.dev/laminas-db/table-gateway/#tablegateway-lifecycle-events
I’m just happy to see that I’m not the only one who puts code that does things like database inserts in a totally inappropriate place (indexAction) when I just want a real quick-and-dirty test 🙂
Yes, this is ok for quick and dirty check 😀
Hello, your use case is very good, I would like to know how do I create a class that does the attach without having to be in the controller
You should can use in your own listener or apply in Module class, this posts may help:
– https://samsonasik.wordpress.com/2013/03/30/zend-framework-2-getting-closer-with-eventmanager/
– https://samsonasik.wordpress.com/2014/01/08/zend-framework-2-move-out-your-listeners-from-module-class/
– https://samsonasik.wordpress.com/2013/05/18/zend-framework-2-register-event-listeners-in-configuration-file/
Thank you very much, it is very difficult to find quality articles related to zend/laminas on the net, congratulations for the content.
I will see your posts