- Writing a reversible down() How to write a down() that really undoes up() on every installation - idempotent, found by remote id or identifier, safe on every engine - when to leave it out, and how to prove it with up, down and up again.
- Reviewing a migration in code review A checklist for reviewing a migration in a pull request - the file and header, the order, plan(), up() and down(), engines and transactions, ids that differ between installations, personal data, and what the reviewer…
- Large data migrations: batches, time limits and resume Change thousands of objects or rows in one migration without running out of memory or locking the site - batches, transactional() returning false, an idempotent up(), pauses, maintenance mode, and resuming a run that…
- A tour of the source tree Every top-level directory and entry point of an Exponential checkout from a PHP developer's point of view - where the kernel, the libraries, the commands, the settings, the tests and the generated files live, and which…
- Migration commands Every exp:migration command in one table - what it does, when to use it, its most used options and a link to its generated reference page - with the options all of them share, the exit codes, the machine output and the…
- Migrations: policies, views and events The policies of the module migration and which views check them, the seven views with their addresses, the dashboard block and its fetch function, the ezpEvent events a run sends with their parameters, and the audit…
- Coming from SQL update files For teams that ship database changes as hand-written SQL files and update scripts - how one change becomes one PHP migration that knows every engine, is recorded, captioned and committed, with a worked example of an…
- How a request runs in PHP The path of one web request through Exponential's PHP code - index.php, autoload.php, ezpKernel and ezpKernelWeb, request initialization, URL translation, access checks, the module view, the pagelayout and shutdown…
- Migration recipes Twenty-five task pages for migrations in Exponential 6.0.15, each with what you will have at the end, the steps and their output, the complete PHP migration, how to check it, how to take it back and the next step - from…
- Setting up a PHP development checkout A working checkout for PHP work on Exponential - clone, Composer, a SQLite installation, the dev environment name, the development tools in .devtools/, the git hooks, debug settings and the commands you run every day.
- Supported PHP versions: 7.4 to 8.5 Which PHP versions Exponential 6 supports and how each is tested - PHP 7.4 as the oldest (8.0 for Velocity), 8.5 as the newest, the composer.json constraint, the CI jobs per version, the differences on 8.0, and what to…
- Writing code that runs on PHP 8.0 The rules for PHP code that must run on PHP 8.0, the stock PHP of RHEL 9 (and, without support, on 7.4 for the kernel) - the syntax you may not use, how lib/phpcompat.php and function_exists() guards work, arguments…
- PHP 8 migration notes for your code What to change in older PHP code so it runs cleanly on PHP 8.0 to 8.5 (PHP 7.4 usable without support) under Exponential 6 - dynamic properties, count() on non-arrays, null passed to string functions, SPL return types…
- The coding standard (phpcs.xml.dist) How PHP code in Exponential is written and checked - every rule of phpcs.xml.dist with an example, the forbidden functions, the PHP 8.0 compatibility check, how only new violations fail, and the commands that run the…
- Why the code has no type declarations An explanation of one rule that surprises PHP developers - Exponential code is written without scalar, return and property types and without strict_types - what is allowed instead, how types are documented and checked…
- Static analysis with PHPStan How Exponential uses PHPStan - level 1 over kernel/ and lib/ with a baseline of existing findings, what is excluded and why, running it locally and in CI, reading a finding, fixing it instead of baselining it, and…
- Git hooks and make targets The local checks of the Exponential repository - the pre-commit, commit-msg and pre-push hooks in .githooks/, every make target from make check to make lint80-all, the file manifest share/filelist.md5, and the commit…
- CI and reproducing a red check The continuous integration of the Exponential repository from a PHP developer's side - the Quality, PHPUnit, Performance and CI health workflows, what blocks, how a pull request is tested, and the local command for each…
- PHPUnit without a database How Exponential's PHPUnit setup works for PHP developers - phpunit.xml, tests/bootstrap.php, the test suites and excluded groups, PHPUnit 10 to 13 across PHP 8.1 to 8.5, writing a DB-less test for kernel or extension…
- Database and live tests Tests that need a real database or server - the database group and tests/runtests.php with a DSN and a database per test, the MongoDB and live HTTP tests and their environment variables, how to pass passwords safely…
Documentation license
This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.
Exponential Copyright © 1998-2026 Exponential Foundation and 7x