Exponential for PHP developers
This page is for PHP developers who are new to the Exponential code base. It explains what kind of PHP application Exponential is, which conventions you will meet in the first hour, and where they differ from the frameworks most PHP developers know today. The detailed pages of this section build on it.
Contents
- What the code base is
- Five things that surprise PHP developers
- The building blocks you will write
- What the project checks on every change
- Where to go next
What the code base is
Exponential is an open source content management system and PHP application framework, licensed under the GNU GPL,
version 2 or later (composer.json, "license": "GPL-2.0-or-later"). The code base has been developed since 1999,
first under the name eZ Publish, a product its creator discontinued after almost 18 years; 7x kept it alive, and the
product has been called Exponential since August 2025 (Who is 7x?).
For a PHP developer that history matters in one way: the code is older than Composer, PSR-4 and namespaces, and it kept its own conventions. They are consistent and documented, and the project's checks enforce them on new code.
| Part | Directory | What it holds |
|---|---|---|
| Kernel | kernel/ | content model, modules and views, datatypes, workflows, users and roles, the request kernel (kernel/private/classes/ezpkernelweb.php) |
| Libraries | lib/ | general building blocks: lib/ezutils (eZINI, eZDebug, eZSys, eZHTTPTool, eZExecution), lib/ezdb (eZDB and the drivers), lib/eztemplate (the template engine), lib/ezfile, lib/ezi18n and more |
| Extensions | extension/ | everything added on top, shipped or your own: modules, datatypes, operators, designs, settings |
| Settings | settings/ | the INI defaults; installations override them in settings/override/ and settings/siteaccess/ |
| Entry points | index.php, bin/php/*.php, runcronjobs.php | the web front controller, the command line scripts and the cronjob runner |
A tour of every directory is on A tour of the source tree.
Five things that surprise PHP developers
- Class maps, not PSR-4. Classes are found through generated arrays:
autoload/ezp_kernel.phpfor the kernel andvar/autoload/ezp_extension.phpfor the extensions, written byphp bin/php/ezpgenerateautoloads.php. A new class that is not in the map does not exist (Autoloads and class maps). - The kernel style has no type declarations.
phpcs.xml.distrefusesdeclare( strict_types=1 ), scalar parameter types, return types and property types in new code, to match the existing code and keep PHP 8.0 working (Why the code has no type declarations). array( ... ), not[ ... ], and spaces inside parentheses.foo( $a, $b ),if ( $a ), the opening brace of a function on its own line (The coding standard).- Settings are INI files in layers.
eZINI::instance( 'site.ini' )->variable( 'Block', 'Key' )reads the value after the kernel defaults, the extensions, the siteaccess and the installation's overrides were merged (Reading settings with eZINI). - Much state is static. Singletons such as
eZINI::instance(),eZDB::instance()and in-memory caches live in static properties. Under PHP-FPM each request starts fresh; under Velocity's persistent workers they survive between requests unless the kernel resets them (Static state traps).
The building blocks you will write
| You want | You write | Page |
|---|---|---|
a new screen at /<module>/<view> | a module with views | Write your first module view |
| a command line tool | a class extending Exponential\Runnable\Command | Write a console command |
| scheduled work | a cronjob part | Write a cronjob part |
| data for templates | a fetch function | Write a fetch function |
| a template filter or helper | a template operator class | Write a template operator in PHP |
| a new field type | a class extending eZDataType | Write a datatype |
| a step in a workflow | a class extending eZWorkflowEventType | Write a workflow event type |
| data in your own table | a class extending eZPersistentObject | Persistent object definitions in depth |
| JSON for your own JavaScript | an ezjscore server function | ezjscore JSON endpoints in PHP |
| a reaction to something the kernel does | an event listener | Events, listeners and filters |
What the project checks on every change
| Check | Tool | Page |
|---|---|---|
| PHP syntax, also with PHP 8.0 | php -l, make lint80 | Writing code that runs on PHP 8.0 |
| Code style of changed files | make phpcs (phpcs.xml.dist) | The coding standard |
| Static analysis | make phpstan (level 1 with a baseline) | Static analysis with PHPStan |
| Unit tests | vendor/bin/phpunit | PHPUnit without a database |
| The file manifest | make manifest-check | Git hooks and make targets |
Where to go next
- Follow The PHP developer's reading path in order.
- Set up a checkout: Setting up a PHP development checkout.
- Learn the request: How a request runs in PHP.
Related pages
- PHP Developers: start here
- Kernel architecture
- Application creators: start here, the extension developer book
- Software Engineers: start here, Web Framework Developers: start here
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.