TRA User-centric PHP framework

What is OTRA? What is its goal?

OTRA is a PHP framework in alpha version at the time of writing used to create websites and web applications.

Many tasks are automated but the framework is user-centric, not developer centric so the performance is more important than productivity.

Want to test it right now?

composer create-project otra/skeleton --remove-vcs yourProjectFolderName

You wish to have the latest features and bugfixes?

Update the OTRA version in composer.json by replacing ^1.0.0@dev by dev-develop then type :

composer update

Want to contribute?

Why use a framework?

A framework is not mandatory but that will provide you a structure and allow you to save time by re-using generic code in order to focus on other areas. For example, no need to recreate a routing system or an MVC structure.

You can then fully focus on the business rules, the core structure being upgradeable.

When use a framework?

If you have specific needs or specific business rules, you will use a framework to be able to develop an application that suits them perfectly while still being innovative.

Otherwise, maybe a CMS (Content Management System) or a packaged professional solution (CRM, e-commerce solution, etc.) will be sufficient, and you won't have to reinvent the wheel.

Main sections>Configuration>Server configuration>Nginx configuration

Previous section : PHP requirements

Nginx configuration

There is no .htaccess for Nginx, see Apache section for that.

Now we will edit the configuration file /etc/nginx/sites-available/

You can now generate a server configuration file with this command :

otra genServerConfig /etc/nginx/sites-available/ dev

You will need to use this configuration file or something similar according to your architecture...

In this file, the penultimate location block indicates the entry point of the framework.

The second one handles the php parsing via PHP-FPM.

It also specifies the kind of environment you want like development or production (dev or prod) like so ...

fastcgi_param APP_ENV dev;

and the database test ids ...

fastcgi_param TEST_LOGIN root; fastcgi_param TEST_PASSWORD '';

For your own database, you can use the same system.

/!\ Of course, change those ids to something more secure !

Do not hesitate to look at the Nginx boilerplate for further information on how to complete your configuration.

Once it is done, create a symbolic link to activate your site :

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

You can disable your site later with the unlink command.

Create the logs folder if you did not do it yet :

sudo mkdir /var/log/nginx/yourdomain

Verify that nothing already listens on port 80 and, of course, (re)start PHP-FPM and Nginx :

sudo service php7.3-fpm start && sudo service nginx start

Main sections>Configuration>Server configuration>PHP requirements

Previous section : Configuring hosts

PHP requirements

You also need to activate the library inotify.

Inotify is a PECL extension that will allow OTRA to create file watchers.

To install inotify, you will need PEAR and some development dependencies like phpsize (phpize) :

sudo apt update sudo apt install php-pear php7.3-dev sudo pecl install inotify echo "extension=inotify" > /etc/php/7.3/mods-available/inotify.ini sudo phpenmod inotify

If php looks in wrong folders for inotify configurations, you may have not clean old php installation.

For example, for a PHP 7.2 installation remove it that way :

apt purge php7.2 php7.2-common

Next section : Nginx configuration

Main sections>Configuration>Server configuration>Apache configuration

Apache configuration

I recommend to not use .htaccess file when possible, it allows to deactivate the functionality that searches for this kind of files. You can then put :

AllowOverride None

In the future, you will be able to generate a server configuration file with this command :

otra genServerConfig /etc/nginx/sites-available/ dev apache

...but it only works for Nginx as we speak.

Next section : Command line requirements

Main sections>Configuration>Server configuration>Command line requirements

Previous section : Apache configuration

Command line requirements

On *nix systems

You also have to set environment variables in your shell configuration to use the command line in good conditions.

It may be ~/.bashrc, ~/.zshrc or another location depending on your environment.

export TEST_LOGIN root; export TEST_PASSWORD '';

On Windows


Next section : Configuring hosts

Main sections>Configuration>Project configuration>Tips for faster synchronization

Previous section : Routes configuration file

Tips for faster synchronization

If your editor does not synchronize fast enough with external modifications (in the case of file watchers for example), you can check this :

cat /proc/sys/fs/inotify/max_user_watches

If this shows a lower number than 524288 then edit the file /etc/sysctl.conf and adds this line :

fs.inotify.max_user_watches = 524288

Once you have done that, you must apply this change by doing :

sudo sysctl -p --system

Don't forget to restart your IDE after that operation.

In the case of PHPStorm, you also can go to :

Settings > Appearance & Behavior > System settings > Synchronization

Here you can put Save files automatically if application is idle for to 1 second.

This way, you will see much faster your JavaScript files generated by TypeScript for example.

Next section : Watching files

Main sections>Configuration>Project configuration>Watching files

Previous section : Tips for faster synchronization

Watching files

On Unix systems

You can set up a watcher to listening for class mapping, typescript files, scss files and route configuration updates by typing this command :

php console.php genWatcher

This command only work on unix systems because it uses the inotify command.

Do not hesitate to look the following section to improve synchronization speed if needed.

As usual, you can filter what you want to watch with parameters, see the command help for more information.

On Windows

If you use PHPStorm, you can set up file watchers that will launch manual commands available like otra genAssets etc.

For the scopes, you need to copy the folder scopes in your related .idea folder.

For the file watchers, you can import them via File > Settings > Tools > File Watchers > Import.

Main sections>Configuration>Project configuration>Routes configuration file

Previous section : Main configuration files

Routes configuration file

The file can be as simple as this one.

<?php return [ 'index' => [ 'chunks' => ['/', 'App', 'frontend', 'index', 'IndexAction'], 'prefix' => 'otra\\user', 'resources' => [ 'template' => true ] ] ]; ?>
  • index is the name of the route.
  • chunks contains many parameters :
  • the url;
  • the app name;
  • the bundle name;
  • the controller name;
  • the action name. Always specify this name in PascalCase.
  • prefix is optional and contains the prefix to add to the action to find it
  • resources contains information on client side.
  • template at true, it will tell that it is a static page.
    It allows performance improvement by caching the generated page.
  • Assets - CSS and JS.
    Here x can be css or js. All these parameters are arrays containing x file names.
    No need to put their extension.
    • app_x for application related files. E.g.:
      'app_js' => ['test'] for /myProjectPath/bundles/resources/js/test.js
    • bundle_x for bundle related files. E.g.:
      'bundle_css' => ['test'] for /myProjectPath/bundles/HelloWorld/resources/css/test.css
    • core_x for OTRA/core related files. E.g.:
      'core_css' => ['test'] for /myProjectPath/vendor/otra/otra/src/resources/css/test.css
    • module_x for module related files. E.g.:
      'module_js' => ['my/test'] for /myProjectPath/bundles/HelloWorld/frontend/resources/js/my/test.js
    • print_css for print related files. Same path as module assets. E.g.:
      'print_css' => ['my/test'] for /myProjectPath/bundles/HelloWorld/frontend/resources/css/my/test.css
  • bootstrap must be an array that contains TO COMPLETE
  • post must be an array that contains default POST parameters
  • get must be an array that contains default GET parameters
  • session must be an array that contains default SESSION parameters

The route order is important so be sure to put the most generic ones at the end.

When we specify resources files, we can order them by telling their loading position like that :

'resources' => [ '_css' => ['users'], 'bundle_css' => ['backendUsers'], 'core_css' => ['lightbox'], '_js' => ['_5'=>'users'], 'bundle_js' => ['base', 'backend', 'form', 'notifications'], 'core_js' => ['_4' => 'lightbox'] ]

lightbox.js will be loaded before users.js.

Next section : Tips for faster synchronization

Main sections>Configuration>Project configuration>Main configuration files

Main configuration files

Do not touch bundles/config/Config.php, it is a generated file. This file can be moved in a later version of the framework.

The main configuration file is config/AllConfig.php. It contains generic configuration that will work for development and production environments.

Values that can be modified in this file :

  • CACHE_PATH : location of the generated files, especially the productions files for now
  • VERSION : used for dynamic caching of CSS/JS resources
  • RESOURCE_FILE_MIN_SIZE : aimed to load CSS/JS resources directly into the templates if their size is under this size.

The related environment specific configuration files are in config/dev/AllConfig.php and config/prod/AllConfig.php respectively.

Beware, in this file, the driver name must match with the related class name in OTRA (e.g. : Pdomysql).

You must, even empty (for the time being), have a file bundles/App/config/Config.php where App is the name of ... your application.

It will contain additional configuration that you want to pass like paths for example.

In the file config/AdditionalClassFiles.php, must contain the paths of OTRA classes that are included dynamically via require(_once)/include(_once) directives. Most of the time, you do not have to touch this file.

You can set the way the genWatcher task compile assets by choosing between two modes :


Put one of those values into AllConfig::$compileMode to choose the mode.

Next section : Routes configuration file

Main sections>A few last tips

Previous section : HTTP headers

A few last tips

To know all the commands simply type :

php console.php

As specified in this help, you can have more detailed help on a command :

php console.php help myCommand

To avoid that Composer adds autoloader files which are useless with OTRA, you should not pass by PHPStorm (until we can add the option --no-autoloader) to update Composer packages.

Next section : Troubleshooting

Main sections>Troubleshooting

Previous section : A few last tips


Be sure to put an ending PHP tag in your PHP files as the OTRA PHP rewriting system needs them to work correctly.

Next section : Contributing

Main sections>HTTP headers

Previous section : All about database

HTTP headers

You can configure the Content Security Policy and the Feature Policy in your actions.

Feature Policies have default values for the development environment, not for the production one.

You can override default values for development environment like so :

MasterController::$featurePolicy['dev']['sync-script'] = "'self'";

... and defining production Feature Policy like so :

MasterController::$featurePolicy['prod'] = [ 'accelerometer' => "'none'", 'ambient-light-sensor' => "'none'", 'autoplay' => "'none'", 'battery' => "'none'", 'camera' => "'none'" ];

The configurations will be overwritten.

You can define CSPs almost the same way :

MasterController::$csp['dev'] = MasterController::$csp['prod'] = [ 'connect-src' => '\'self\'' ];

The configurations will be merged.

Next section : A few last tips

Main sections>Generating everything you need

Previous section : Cache management

Generating everything you need

Updating routes

Once you have configured your application, don't forget to do :

php console.php upConf

It will optimize your configuration by generating an aggregated minified configuration file.

Generating the class mapping

You can generate a class mapping via this command :

php console.php genClassMap

You can pass 1 as parameter to directly show the classes of the class mapping.

This command can be used via a file watcher when adding/modifying a file.

Optimizing your server code for production

You can generate optimized versions of your routes (php code mostly) like this :

php console.php genBootstrap

Generating assets for production

You can generate optimized versions of your assets ... :

php console.php genAssets

Next section : All about database

Main sections>Contributing>CSS side or SCSS side

CSS side or SCSS side

Coding style

  • Do not use uppercase in classes, the css rules and properties do not use them => consistency.
  • Use the BEM (Block Element Modifier) syntax. Documentation

Best practices

  • Use SCSS or SASS. SCSS is probably best because if one day, it becomes useless due to CSS enhancement ... SCSS has almost the same coding style, so it will be simpler to adapt the code.
  • Keep the lowest specificity as possible. Some people even say never use ids but classes instead for re-usability !
  • Use border: 0 and not border: none (shorter)

Next section : Generic rules

Main sections>Contributing>PHP side

Previous section : Javascript side

PHP side

Coding style

  • Organize use statements particularly when they share path e.g. :

    use config\{All_Config, Routes};

Best practices

  • Use const instead of define when possible. See this Stack Overflow post.
  • Use a class only when you cannot do it procedurally or when you need a scope.
  • Always put a PHP documentation block unless the meaning is obvious. Ex :

    public function getFirstName() : string { return $this->firstName; }

    Here, there is no need for documentation.

  • Always type the variables and put a return type
  • Do not calculate the length of an array in the condition statement of a loop.

    Put it on the assignment statement. This allows us to not calculate length at each loop.

    Wrong :

    for ($i=0; $i < count($myArray); ++$i) { [...] }

    Good :

    for ($i=0, $myArrayLength = count($myArray); $i < $myArrayLength; ++$i) { [...] }
  • Always use === instead of == unless we cannot do otherwise. == can do conversions so === performs better.

Next section : Shell side

Main sections>Contributing>JavaScript side

Previous section : HTML side

JavaScript side

Best practices

  • Use TypeScript, it provides types, annotations, object-oriented code and so more. So type every variable, put return types …
  • Use the use strict statement in order to have a clean code
  • Use border: 0 and not border: none (shorter).
  • When you want to use jQuery, learn how jQuery do it and then use vanilla js instead. To help you : You might not need jQuery.

Next section : PHP side

Main sections>Contributing>Generic rules

Previous section : CSS side or SCSS side

Generic rules

Coding style

  • Tabulation :
    • Spaces, not tabs
    • 2 spaces => to avoid to scroll horizontally when they are much nestings
  • Curly brackets on the same column
    • more aeration
    • easy to see if there are some missing curly brackets, counting curly brackets, above all when there are far away
  • Put a blank line before and after block statements (if, for, while etc.)
  • 80 characters per line maximum in order to be able to have 2 files opened side by side on a laptop screen.
  • Use PascalCase for classesName, SCREAMING_SNAKE_CASE for constants, camelCase for the rest.
  • If the line of code of a function signature is too long, we have to put the parameters under, one parameter by line.

Example :

public final function renderView( string $file, array $variables = [], bool $ajax = false, bool $viewPath = true ) : string

Next section : HTML side

Main sections>Contributing>Shell side

Previous section : PHP side

Shell side

Coding style

  • Use snake_case for unexported variables and SCREAMING_SNAKE_CASE for constants and exported variables.
Main sections>Contributing>HTML side

Previous section : Generic rules

HTML side

  • Don’t use the attribute type="text" on input is the default.
  • No need to respect XHTML norm unless we want to use that document with XML code. We can use <input> instead of <input/> for example, it is shorter.
  • If we can, avoid to use <br> and prefer CSS classes instead.
  • Don’t forget to use ARIA. Here is the documentation.
  • Don’t forget to use structured data. Here is the documentation.
  • Don’t forget to use microdata. Here is the documentation.
  • Don't forget ... You can use this source code for a good start : HTML5 Boilerplate.

Next section : JavaScript side

Main sections>Cache management

Previous section : Configuration

Cache management

Beware! If you want to use console to generate files in the cache directory, assure you that :

  • the directory cache exists
  • the directories php, js and css in the cache directory exist

Next section : Generating everything you need

Main sections>All about database>Database fixtures

Database fixtures

Your bundle database fixtures must be in the folder bundles/bundleName/config/data/yml/fixtures.

A fixture file must be in YAML and looks like this :

table_name: fixture_name: my_id_column: 1 my_other_column: 'Main topic' a_timestamp_column: '2010-12-31 00:00:00' unsigned_column: 1 fixture_name_bis: my_id_column: 2 my_other_column: 'Second topic' a_timestamp_column: '2010-12-32 00:10:00' unsigned_column: 2 fixture_name_ter: my_id_column: 3 my_other_column: 'Third topic' a_timestamp_column: '2010-12-33 00:20:00' unsigned_column: 3 [...]

When you want to make reference to a fixture of another table, we must put the fixture name instead of the value.

Next section : Database schema

Main sections>All about database>Database schema

Previous section : Database fixtures

Database schema

Your bundle database must be in the file bundles/bundleName/config/data/yml/schema.yml.

It must follow this kind of architecture :

table_name: columns: my_id_column: type: int notnull: true auto_increment: true primary: true my_other_column: type: varchar(255) notnull: true a_timestamp_column: type: timestamp notnull: true unsigned_column: type: tinyint(1) unsigned [...] another_table_name: columns: my_foreign_id_column: type: int notnull: true primary: true my_foreign_id_column_two: type: int notnull: true primary: true a_column: type: int notnull: true relations: other_table: local: my_foreign_id_column foreign: id constraint_name: relation_name other_table_bis: local: my_foreign_id_column_two foreign: my_id_column constraint_name: another_relation_name other_table: columns: [...] other_table_bis: columns: [...]

It remains SQL features that are not handled yet but feel free to create issues about those that are missing.

Main sections>Installation


You can install OTRA via Composer.

OTRA has its own system to load classes, so we can skip autoloader generation.

At the time of writing, we cannot do this with the require command so we first force deletion of the vcs folder, and then we use the update command with the --no-autoloader parameter.

composer create-project otra/skeleton --remove-vcs yourProjectFolderName

If you want to use the latest version of OTRA in development, you can put in your composer.json this line :

"otra/otra": "dev-develop as 1.0.@dev"

Next section : Configuration


New OTRA version : 1.0.0-alpha.2.6.0

By Lionel Péramo from Wexample Labs, the

Description of the transition from the version 1.0.0-alpha.2.5.1 to the version 1.0.0-alpha.2.6.0 :


  • Updates the nginx configuration file generated by the OTRA task to prevent robots.txt and sitemap.xml pages to send 403 to search engines
  • Adds a .gitattributes file to prevent adding extra stuff with composer create-project
  • Multiple namespaces in one file is now handled even if it's discouraged.
  • We can now enforce a message for commands that fail when launched by the WorkerManager
  • updateConf task now accepts a mask to choose which kind of configuration files we want to update
  • Adds new utilities functions getIfExists and getArrayIfExists in the OTRA session
  • Overall improvement and fixes
  • It now uses PHP 8.1

Command line

  • Clearer errors
  • Adds the possibility to use the POSIX syntax for console parameters


  • There is now only one profiler. It contains :
    • logs
    • request/response information
    • routes
    • SASS information on dependencies
    • SQL inspection
    • template structure tool
  • We can now select the file and line of an SQL request to be able to copy them easily


  • Allows to have a prefix behind the action to launch in case where we use an OTRA module used in another project. The prefix is used to prevent conflicts.
  • Adds a redirection system to call a controller/action from another one. There is a dedicated parameter that tells us if we have used an internal redirection or not.
  • Adds HTTP verbs and Content-Type header handling


  • Load paths are now handled in order to reduce the paths length
  • Adding forward handling in genWatcher task.


  • Adds prepared statements to the DBAL
  • It now handles the ON UPDATE feature and the comments in the database schemas
  • We can now use indexes with the OTRA database import/export system
  • New methods added in the DBAL :
    • fetchAllAssoc
    • fetchAllByPair
    • rowCount
    • setAttribute
    • getAttribute


New OTRA version : 1.0.0-alpha.2.3.0

By Lionel Péramo from Wexample Labs, the

Description of the transition from the version 1.0.0-alpha.2.2.0 to the version 1.0.0-alpha.2.3.0 :

  • The Content Security Policy (CSP) is now dynamically handled via OTRA. Nonces can now be generated for the attributes nonce with the function parent::getRandomNonceForCSP() in the templates. You will be able to use the policy script-src 'strict-dynamic'.
  • A security directive has been added in the server configuration generation task to hide sensible information about your server like the Nginx version for example. The sources maps are now also handled in the referrer conditions.
  • The related directives to the "Feature Policy" are now handled and have default values for the development environment. Those directives and the CSP are defined in the OTRA Master Controller and are available at any moment.
  • If a file is named sw.js or serviceWorker.js then they will be automatically moved in the /web folder when generated by the otra buildDev task.
  • The OTRA global constants that should not be modified are now centralized and generated by the task otra createGlobalConstants.
  • The dump" functions are now different if we come from the command line or from a web page.
  • Management of the internal PHP server task reviewed and improved.
  • Many bug fixes.


New OTRA version : 2023.0.0

By Lionel Péramo from Wexample Labs, the

Description of the transition from the version 1.0.0-alpha.2.6.0 to the version 2023.0.0 :


  • # 78 : [Bug] Fixes assets loading.


  • # 67 : [Feature] Limit the numbers of workers that work at the same time in the deployment task.

  • # 34 : [Feature] Add 'parallel' to the list of recommendations

Command line

  • # 13 : [Feature] New sqlMigrationExecute task :
    - Help and its automated test
    - Task that executes a database migration file and its test

  • # 14 : [Bug] OTRA binary can now be launch directly via bin/otra.php.

  • # 13 : [Feature] New sqlMigrationGenerate task :
    - Help and its automated test
    - Task that generate a blank database migration file and its test


  • # 100 : Enhances security by adapting database connection error messages based on the application environment.

Database Configuration

  • # 97 : [Enhancement] Adds configurable charset and dsnDriver fields to the database configuration.


  • # 71 : [Cleaning] Cleaning via PHPStorm inspection

  • # 58 : [Feature] Improves error handling in cleanFilesAndFolders.php.

  • # 57 : [Feature] Adds paths parameters for SASS and TypeScript binaries. Compresses SASS files.


  • # 66 : [Feature] We should be able to use JS modules now.


  • # 99 : [Feature] Adds a simpleLogTo function for straightforward logging.


  • # 94 : [Feature] Improved 404 error resolution by detailing tried routes and their failure reasons in Router.

  • # 93 : [Bug] Class name conflicts with external libraries resolved in otra genBootstrap production deployment.

  • # 88 : [Bug] SVGs are no longer broken by HTML minification.

  • # 87 : [Performance] Optimized performance and updated code comments for clarity in the genClassMap task.

  • # 86 : [Performance] Refines resource compilation buildDev task. Significant performances optimizations have been applied especially on the SASS and TypeScript side.

  • # 84 : [Bug] Fixed namespace conflict in router for development and production environments.

  • # 83 : [Bug] Fixes $viewsPath parameter handling in the renderView method.

  • # 82 : [Bug] Fixes getRouteUrlWithoutParameters function when using URLs without named parameters.

  • # 81 : [Bug] Fixes incorrect closure handling for preformatted tags during minification.

  • # 75 : [Bug] The process management object is optimized to prevent interruptions in our system during prolonged tasks, and error handling has been enhanced for more reliable administration.

  • # 74 : [Bug] Fixing environment issues on compiling assets. We will now have only one folder to specify to compile assets.

  • # 29 : [Feature] We can now use Redis

  • # 30 : [Feature] Handle OPTIONS HTTP verb

  • # 65 : [Bug] Adds tests folder to the class maps to prevent PHPUnit failing because of bad autoloading mechanism.

  • # 64 : [Cleaning] Removes PHP sessions of the deployment mechanism.

  • # 63 : [Bug] Removes hardcoded credentials in DatabaseTest.php.

  • # 62 : [Bug] Checks if the colors are loaded and loads them if it is not the case.

  • # 61 : [Cleaning] Adds a key in $unprotectedFields in the function removeFieldsScopeProtection of the file /src/tools/removeFieldProtection.php.

  • # 60 : [Tests] genWatcherTask.php : Adds information on what watches are added. Better handling of removed watches.

  • # 55 : [Bug] Fixes the default content type in the router and bootstraps

  • # 54 : [Miscellaneous] Cleaning

  • # 53 : [Feature] Updating OTRA requirements

  • # 15 : [Feature] Migration to PHP 8.2

PHP tests

  • # 48 : [Cleaning] Replace $preserveGlobalState declarations by annotations

  • # 56 : [Miscellaneous] Cleaning and fixing

  • # 52 : [Feature] Update tests for PHPUnit 10

Profiler - Log Utilities

  • # 101 : Adds comprehensive unit tests for log utility functions used in the advanced profiler interface. Enhances reliability.


  • # 98 : [Enhancement] Automatically updates JavaScript routing file when updating routes configuration via updateConf.

  • # 91 : [Bug] Now we can organize routing files with folders.


  • # 96 : [Bug] Fixes the issue where enum values are incorrectly converted to uppercase.

  • # 95 : [Bug] Fixed the issue where CURRENT_TIMESTAMP or NOW couldn't be used for a field of type timestamp. Also improved database to YAML schema import.

  • # 59 : [Tests] Adds ON DELETE RESTRICT clause when testing database schema.


  • # 92 : [Bug] We do not alter CSP rules script-src-attr, script-src-elem, style-src-attr, style-src-elem anymore.

  • # 90 : [Bug] Security files are always loaded once.

  • # 76 : [Bug] Restoring nonces for CSS.

  • # 71 : [Bug] Removes interest-cohort as it is no more used by Google.Cleaning via PHPStorm inspection.
    Removes 'self' when using strict-dynamic given that 'self' is ignored in this case.
    Removes strict-dynamic for the style-src directive as it is not compatible (nonces removed too).


  • # 51 : [Feature] AVIF management in Nginx server configuration


  • # 80 : [Bug] Fixes usage of quotes in attribute values.

  • # 79> : [Bug] Enhanced handling of '<' and '' characters during minification.

  • # 33 : [Bug] Fixes overly simplistic method of minifying HTML templates.


New OTRA version : 1.0.0-alpha.2.5.0

By Lionel Péramo from Wexample Labs, the

The blog is finally translated entirely into Spanish.

A lot has been done since the last article and now all of that is available.

Description of the transition from the version 1.0.0-alpha.2.4.0 to the version 1.0.0-alpha.2.5.0  :


  • OTRA uses PHP8+
  • Feature-Policy is now deprecated and OTRA will then now use 'Permissions-Policy' syntax
  • The cache folder has been reorganized by putting core files into their own folders, so we can clearly see the project related routes
  • Architecture tasks have now their own folders

New things


  • Documentation improvements about installation instructions
  • Adds a lot of automated tests

Console tasks

  • Custom console tasks are now handled
  • New routing generation task that will put all the routes in a JavaScript file that can be loaded automatically by OTRA
  • New parameter to force creation when things already exists when we are in a "not interactive" mode
  • New test suite configuration file for console architecture tasks
  • Commit number added to the version task and in the debug bar
  • New task checkConfiguration to check the routes configuration
  • New task to convert images to other format like from jpg to webp
  • genWatcher task :
    • usable ... as inotify can now work again
    • new parameter to choose when we compile ...on save or on update
    • it now uses a SASS dependencies tree from a cached file

New heavy profiler

  • Adds a heavy profiler that have its own dedicated page
  • Adds data on SASS files like a dependency tree


  • Security improvements in the generated headers
  • Adds cache handling
  • Adds configuration for Progressive Web App handling


  • Psalm, SASSDoc and PHPDoc configuration have been added
  • TSLint is now deprecated so OTRA will use ESLint instead


  • SASS import keyword is deprecated so OTRA use use directive now
  • Print stylesheets are now fully handled
  • Debug bar has been renovated
  • Harmonization of the messages and colors of the console has been done
  • Exception page has been renovated
  • OTRA stylesheets handle dark mode

Fixes and cleaning


  • Old TODOs removed and put in others places to clean the code
  • Better exception messages (context was not always given before)
  • Fixes the model creation task when using 'one model from nothing' mode
  • Fixes some cases in the router
  • Starts session only for dynamic routes
  • Fixes the WorkerManager when there are more than 1 or 2 workers in parallel
  • Fixes AJAX mode


New OTRA version : 1.0.0-alpha.2.4.0

By Lionel Péramo from Wexample Labs, the

The blog is finally translated entirely into French. Description of the transition from the version 1.0.0-alpha.2.3.0 to the version 1.0.0-alpha.2.4.0  :

  • No PHP ending tags needed anymore
  • The constructors of the actions should now be called like this:
    public function __construct(array $baseParams = [], array $getParams = []) { parent::__construct($baseParams, $getParams);
  • SonarQube configuration added. PHPUnit configuration updated.
  • Performances improved.
  • Lot of refactoring (do not hesitate to look at .dist files):
    • PSR-12 norms adjustments
    • more constants to ease maintenance
    • case consistency
    • main configuration files
    • framework files organization
  • The genAssets task will now be able to compress the SVG images automatically.
  • The HTML comments are now removed from the templates generation.
  • The Content-Security-Policy and Feature Policy directives are now handled but not for the Progressive Web App yet.
  • Update system better integrated with Composer.
  • The repository better suits the GitHub norms for contributions.
  • New automated tests.
  • New workers system to handle parallel processing. The deployment system now uses it.
  • New dump function that is no more dependant of XDebug.
  • New templates visualization tool to see templates as the templates motor see them. Not yet available through the debug bar.
  • The CSS code must now respect the StyleLint configuration.


New OTRA version : 1.0.0-alpha.2.5.1

By Lionel Péramo from Wexample Labs, the

This version is only corrective.

Description of the transition from the version 1.0.0-alpha.2.5.0 to the version 1.0.0-alpha.2.6 :


  • Automated tests fixed and two new tests added for the task genAssets
  • Regressions fixed and harmonization of the features related to the JavaScript compilation/generation
  • The task genWatcher does not hang anymore when there is an error in your TypeScript code or if we remove files
  • Clearer informational message in profiler when SASS / SCSS cache is not present
  • Correction of the .dist reference file for the routes
  • Correction of a bug in the CSP security rules on the styles side
  • Fixed Symfony YAML package version because it was blocking the generation of test coverage by PHPUnit

Debug bar

  • More responsive debug bar
  • Improved support for the latest versions of IE
  • All buttons can now have focus


  • Fixed cache management in generated server configuration files
  • Creation of an additional generated server configuration file linked to the cache


Blog arrival and a new OTRA version : 1.0.0-alpha.2.2.0

By Lionel Péramo from Wexample Labs, the

Here is finally the brand-new blog which informs you about the new features, evolutions and bug fixes of the PHP OTRA framework.

Description of the transition from the version 1.0.0-alpha.2.1.0 to the version 1.0.0-alpha.2.2.0 :

  • Updates the debug bar positioning in order to always see it whatever the CSS of the project.
  • Reorganization of OTRA controllers and templates.
  • The deploy task is now operational on unix systems.
  • The parameter cookie_samesite has been added with strict value for session cookies for more security.
  • Default values for SQL table properties can now be set in the file schema.yml.
  • The library lightbox.scss can now be used in projects that are not part of the OTRA framework itself.
  • We can now generate the web manifest in its gzipped minified version.
  • The clearCache task has been reviewed to clean more different things in the cache folder like CSS files, JS files, templates, etc.
  • The handling of the protection via HTTP_REFERRER have to be handled in server configuration now and assets will not be loaded via PHP anymore.
  • A new task named genServerConfig allows to generate server configurations. It only handles Nginx for now.
  • A new task named genSitemap allows to generate basic sitemaps for SEO purposes.
  • The sourcemaps generation is now configurable via the AllConfig.php files.
  • Automated tests have been added for the architecture tasks.
  • The database model creation task can now be launched in non-interactive mode.
  • A function has been added in the traduction tools file in order to handle preferred languages via HTTP_ACCEPT_LANGUAGE.
  • Many bug fixes.

Do not forget to modify your namespaces by replacing src by otra when needed.