CodeIgniter 4 usage¶
This page requires daycry/doctrine-codeigniter4. For PHP without CI4, use
the standalone guide and shared configuration reference.
Resolve the adapter¶
The explicit service class is useful for named groups and resets:
use Daycry\Doctrine\CodeIgniter4\Config\Services;
$doctrine = Services::doctrine();
$reporting = Services::doctrine(true, 'reporting');
Both forms return Daycry\Doctrine\CodeIgniter4\Doctrine, which extends the core
wrapper. To construct an unshared adapter directly:
It still obtains ORM/cache/database configuration from CI4. The core constructor
instead requires an explicit Daycry\Doctrine\Configuration.
Framework helper¶
Add the helper to the controller's existing helpers list:
Then:
doctrine_instance() is a global CI4 helper. It is separate from the namespaced,
Composer-autoloaded cache-aside function.
Access mapped entities¶
Configure existing mapping directories in app/Config/Doctrine.php first.
Use your application's mapped entity class:
$em = $doctrine->getEm();
$repository = $em->getRepository(\App\Models\Entity\Product::class);
$product = $repository->find(1);
getEm() returns the EntityManager and raises RuntimeException if the wrapper
does not currently contain one. The public em property is also available.
Multi-database groups¶
Declare connection groups in Config\Database:
use Daycry\Doctrine\CodeIgniter4\Config\Services;
$default = Services::doctrine();
$reporting = Services::doctrine(true, 'reporting');
$freshReporting = Services::doctrine(false, 'reporting');
Names are case-sensitive and must identify a configured group. Implicit calls use
tests in CI4's testing environment, otherwise Config\Database::$defaultGroup.
Implicit and explicit requests for the same effective group share one instance.
Passing false creates a fresh instance.
The adapter uses the same ORM options for each group and constructs separate cache pools with group-specific namespaces. Unknown groups raise ConfigException.
To remove a shared service entry:
The next request creates a new adapter. Do not confuse this with reopening a
manager or with the standalone registry's reset(), which explicitly closes its
managed EntityManager and connection.
Manual result caching¶
The adapter autoloads this namespaced helper through Composer:
use Daycry\Doctrine\CodeIgniter4\Config\Services;
use function Daycry\Doctrine\CodeIgniter4\Helpers\getFromCacheOrQuery;
$reporting = Services::doctrine(true, 'reporting');
$repository = $reporting->getEm()->getRepository(\App\Models\Entity\Product::class);
$total = getFromCacheOrQuery(
cacheKey: 'products:total:v1',
ttl: 300,
queryFn: fn () => $repository->count([]),
dbGroup: 'reporting',
);
Use the same database group for the query and cache lookup. The group argument selects the pool; it does not change the EntityManager captured by the callback.
| Condition | Behaviour |
|---|---|
| Cache hit | Return the stored value |
| Cache miss | Execute the callback, save and return its value |
| Positive TTL | Explicit expiry in seconds |
| TTL zero | Uses the adapter result pool's zero default lifetime |
| Negative TTL | InvalidArgumentException |
resultsCache = false |
Execute the callback without caching |
The helper normalizes PSR-6 reserved key characters and appends a short hash when
normalization is needed. Invalidate or version keys according to application data
changes. In standalone code, use Daycry\Doctrine\Cache\CacheAside with an explicit
pool; see standalone caching.
Reopening the connection¶
For recovery after a closed EntityManager or stale server connection:
The wrapper closes the DBAL connection and constructs a replacement EntityManager over that connection with the existing ORM configuration. It reapplies constructor event listeners/subscribers, types, platform mappings and enabled filters. The configured cache pools and DBAL middlewares remain in place.
Reapply runtime filter parameters, and reload entities through the replacement. Objects loaded through the previous manager are not managed by the replacement. Closing an in-memory SQLite connection discards its database.
SLC statistics and debugging¶
Enable secondLevelCache and secondLevelCacheStatistics in ORM configuration:
$logger = $doctrine->getSecondLevelCacheLogger();
if ($logger !== null) {
$hits = $logger->getHitCount();
$misses = $logger->getMissCount();
$puts = $logger->getPutCount();
}
$doctrine->resetSecondLevelCacheStatistics();
The SLC guide covers mappings and invalidation. The toolbar guide explains debug query capture and the optional per-request statistics filter. Query logging through CI4's PSR-3 logger is separately configurable and does not require the toolbar.