magmasoftwareengineering / slim-module-middleware
Module management for Slim Framework 4
Requires
- php: >=7.4 || >=8.3
- psr/http-message: ^1.1
- psr/log: ^3.0
- slim/psr7: ^1.6
- slim/slim: ^4.13
Requires (Dev)
- vimeo/psalm: ^5.24
README
slim-module-middleware
Hey there! Are you a developer looking for a way to enhance your Slim Framework 4 projects? Look no further than this new software library! With the powerful module loading, you can take your Slim Framework development to the next level.
When you're working on a small project, Slim Framework is great, however, once you need to use it on a complex system, things start to feel a little messy. Therefore, slim-module-middleware was created and has everything you need to separate your code into modules, without breaking the flow of Slim Framework itself. This, in turn, can help your workflow and boost your productivity.
So why wait? Try slim-module-middleware today and see the difference it can make for your Slim Framework projects!
Installation
Installation is only supported through Composer
composer require magmasoftwareengineering/slim-module-middleware
This will install slim-module-middleware and all required dependencies.
Then ensure you have:
$loader = require __DIR__ . '/vendor/autoload.php';
somewhere sensible in the bootstrap of your project.
Usage
Defining a module
A module is simply a collection of Slim Framework-related files e.g. dependencies.php
, middleware.php
, routes.php
& settings.php
, however, it carries one additional overhead - there needs to be a 'Module.php' present in the module folder. An example Module.php
is shown:
<?php
namespace MyApp\Namespace;
use MagmaSoftwareEngineering\SlimModule\AbstractModule;
/**
* Class Module
* @package MyApp\Namespace
*/
class Module extends AbstractModule
{
}
Note, the module does not need to contain any code, just the rest of your module needs to share the same namespace as specified in Module.php - it's simply to help the module loader identify what is a module. The module loader will traverse folders, under the settings => modules => path array, and up to 4 sub-folders deep, looking for 'Module.php' files.
So it is perfectly possible to have within your project something along the lines of:
src/
modules/
admin/
MyAdminModule/
Controller/
dependencies.php
Module.php
routes.php
dashboards/
MyAdminDashboardModule/
Controller/
dependencies.php
Module.php
routes.php
dashboards/
MyDashboardModule/
Controller/
dependencies.php
Module.php
routes.php
MyNonAdminModule/
Controller/
Entity/
Repository/
Service/
dependencies.php
middleware.php
Module.php
routes.php
settings.php
This enables the grouping of related resources and helps reduce the cognitive load on developers by reducing the field of view when focusing on smaller batches of related code.
Settings
<?php
return [
'settings' => [
// ...
// Slim related settings
// ...
'modules' => [
'path' => [
// Modules
dirname(__DIR__) . '/app/modules',// Path to MyApp
dirname(__DIR__) . '/vendor/magmasoftwareengineering',// If you want to load any of our other module-aware libraries
],
'middleware' => [
'MagmaSoftwareEngineering\PhpDebugBar',// Example middleware module
],
'load' => [
'MagmaSoftwareEngineering\Rollout',// Example feature flagging module
'MyAppNamespace\ModuleName',// Your app-specific modules
'MyAppOtherNamespace\OtherModuleName'// Another of your modules etc.
],
'log' => false,// Enable logging of module loading
],
]
];
Middleware
Assuming you have a logger (monolog/monolog or other psr/logger) in the container as 'logger' and the composer autoloader as 'autoload':
<?php
use DI\Container;
use Slim\App
/** @var Container $container */
/** @var \Composer\Autoload\ClassLoader $loader */
$container['autoload'] = $loader;
$container[\MagmaSoftwareEngineering\SlimModule\ModuleLoader::class] = static function (
App $app, Container $container
): \MagmaSoftwareEngineering\SlimModule\ModuleLoader {
$modules = $container->get('settings')['modules'];
return new \MagmaSoftwareEngineering\SlimModule\ModuleLoader([
'app' => $app,
'modulesPath' => $modules['path'],
'logger' => isset($modules['log']) && $modules['log'] === true ? $container->get('logger') : null,
]);
};
Alternatively, if you prefer fluent interface usage:
<?php
use DI\Container;
use Slim\App;
/** @var Container $container */
/** @var \Composer\Autoload\ClassLoader $loader */
$container['autoload'] = $loader;
$container[\MagmaSoftwareEngineering\SlimModule\ModuleLoader::class] = static function (
App $app, Container $container
): \MagmaSoftwareEngineering\SlimModule\ModuleLoader {
$modules = $container->get('settings')['modules'];
return (new \MagmaSoftwareEngineering\SlimModule\ModuleLoader())
->setApp($app)
->setModulesPath($modules['path'])
->setLogger(isset($modules['log']) && $modules['log'] === true ? $container->get('logger') : null);
->init();
};