-
Notifications
You must be signed in to change notification settings - Fork 0
Migration Guide
5.0 is the first release that crossed the bar of breaking BC on purpose. The 4.x line worked but shipped with a handful of mismatches against upstream and a few latent bugs in the DataTables helper. This page is the migration path.
- The 4.x
composer.jsondeclaredphp: >= 8.0but its required dependencies refused to install on PHP 8.0. The runtime requirement is being raised to match reality. -
DB::createImmutable()diverged from the upstreamInitORM\Database\Facade\DBcontract — silently overwriting the shared instance on a second call. Aligning the two changes public behaviour. - The DataTables helper carried bugs (SQLite-incompatible result handling, type errors on string-typed payloads,
recordsFiltered === recordsTotalregardless of the search filter). Fixing them required reshaping the class.
| Area | 4.x | 5.0 |
|---|---|---|
| PHP minimum | declared >= 8.0 (broken — install failed there) |
^8.1 |
DB::createImmutable() second call |
silently overwrote the shared instance | throws DatabaseException
|
DB::createImmutable() return type |
void |
DatabaseInterface |
| Swapping the shared instance | call createImmutable() again |
call DB::replaceImmutable($connection)
|
Instance use of DB ((new DB())->foo()) |
worked via instance __call
|
constructor is now private; the class is final
|
| DataTables namespace | InitPHP\Database\Utils\Datatables |
InitPHP\Database\Utils\Datatables\Datatables |
| DataTables request handling | reads globals directly | accepts a RequestParser (still falls back to globals) |
| DataTables render registry | inline closure array | dedicated Renderer class behind addRender()
|
recordsFiltered |
always equal to recordsTotal
|
computed separately when a search is active |
| Identifier escaping | already correct in 3.x+ via InitORM | unchanged — regression tests added |
Update your CI / Dockerfile / runtime to PHP 8.1 or later. The package will not install on 8.0 because of transitive dependencies.
- "php": "8.0",
+ "php": "8.1",If you call createImmutable() more than once intentionally (between requests in a worker, in test fixtures), switch the subsequent calls to replaceImmutable():
DB::createImmutable($firstConnection);
// … later …
- DB::createImmutable($secondConnection); // silently overwrites
+ DB::replaceImmutable($secondConnection); // explicit swapreplaceImmutable() also accepts a DatabaseInterface instance directly (useful when you cache the Database) and null (clears the slot).
If you were relying on the void return of createImmutable(), no change is required — ignoring the new return value is harmless.
- $db = new DB();
- $db->select('*')->from('posts')->read();
+ DB::select('*')->from('posts')->read();The static surface is unchanged; only the (unintentional) instance path is gone.
- use InitPHP\Database\Utils\Datatables;
+ use InitPHP\Database\Utils\Datatables\Datatables;The class name is the same — only the namespace moved one level deeper. The public API (__construct, __call, setColumns, addRender, addPermanentSelect, orderBySave, handle, toArray, __toString) is unchanged.
The constructor signature is now:
new Datatables(
DatabaseInterface|ModelInterface $db,
?RequestParser $request = null, // ← new
?Renderer $renderer = null, // ← new
);When $request is null the helper still reads $_GET / $_POST / php://input via RequestParser::fromGlobals() — so existing callers keep working unchanged. Injection is opt-in:
$request = new RequestParser($psr7Request->getParsedBody());
$dt = new Datatables(DB::getDatabase(), $request);If your client previously coped with recordsFiltered === recordsTotal even during a search, it will now see the correct smaller value when a search is active. The two paginate / show-X-of-Y behaviours converge to whatever DataTables.js does by default.
Not strictly a 5.0 change — this was always wrong — but PHP 8.2+ emits deprecation notices and a future PHP release makes it fatal. Inside a set{Column}Attribute($value) method, always write through setAttribute():
public function setTitleAttribute(string $value): void
{
- $this->title = strtolower($value);
+ $this->setAttribute('title', strtolower($value));
}See Entities for the long version.
3.x is the version that moved off the pre-InitORM compiler and onto the upstream stack. Most code that worked on 3.x still works on 5.0 — the additional 5.0 changes apply on top. The big things to watch out for relative to 3.x:
-
replaceImmutable()did not exist; the only way to swap was a secondcreateImmutable()(which used to be silent). Same fix as above — switch toreplaceImmutable(). - The DataTables namespace move (step 4 above) applies.
2.x predated InitORM. The migration is closer to a rewrite — getError(), identifier escaping rules, model schema, and entity hooks all changed shape. If you are still on 2.x, the practical recommendation is:
- Cut a branch.
- Replace every
getError()call withtry / catch— exceptions now drive failure paths. - Remove any manual backtick / quote wrapping you did to work around the v2 reserved-keyword bug (see Reserved Keywords).
- Audit
protected $entity = '\App\…';declarations — the 5.0 type isstring(was untyped). - Run your test suite; expect the bulk of changes to be ergonomic, not semantic.
If you hit something that does not have a clear migration path, open an issue — we'll add it here.
- The QueryBuilder surface (
select,where,join,groupBy, …). - CRUD signatures (
create,read,update,delete, plus the*Batchsiblings). - Model configuration (
$schema,$schemaId,$entity,$useSoftDeletes,$createdField,$updatedField,$deletedField, access gates,$credentials). -
Entityaccessors / mutators / dirty tracking. - Transaction semantics (
transaction()with retry andtestMode). - The
log/debug/queryLogsconnection channels.
If something breaks during the upgrade and the fix isn't on this page, please open an issue with:
- The version you upgraded from.
- A minimal code sample that worked on the old version.
- The error you see on 5.0.
Documentation gaps are bugs and get fixed on the same day.
initphp/database · MIT License · part of the InitPHP family
Source · Issues · Discussions · Packagist · Contributing · Security Policy
Getting Started
Core API
ORM
Advanced
DataTables Helper
Recipes
- Index
- — Pagination
- — Search & Filters
- — Upsert / REPLACE INTO
- — Audit Log
- — DataTables Bootstrap
- — Repository Pattern
Reference
Migration & Help