So I had this idea to map my framework's folder structure to namespaces with a dynamic build process.
To give you an idea how this would work here an example structure:
src/
FS/
File/
open.php (function)
Math/
add.php (function)
test.php (function)
MAGIC.php (constant)
Would be translated to:
namespace FS\File {
function open() { /* ... */ }
}
namespace Math {
function add() { /* ... */ }
function test() { /* ... */ }
const MAGIC = /* ... */;
}
There would be no support for classes.
A function would be defined as follows:
<?php
/**
* src/Math/add.php
*
* This is the Math\add module.
*/
return function($require) {
// Require Math\test module.
$test = $require('Math\test');
return function($a, $b) use ($test) {
// Call Math\test function
$test($a, $b);
return $a + $b;
};
};
?>
The outer most function is for providing a new scope (so all previous defined variables are non existing).
Then the $require
variable is for including other modules.
(The idea to require all other dependencies came from node
. I think this would make mocking and testing a lot easier because one could test the module with an overwritten $require
variable.)
And constants could be defined as follows:
<?php
/**
* src/Math/MAGIC.php
*/
return 0xDEADBEEF;
?>
The whole framework would then have a require
method to load a module from filesystem:
/**
* Function that is responsible to load a module.
*/
function require($module) {
static $loadedModules = [];
$modFileName = str_replace('\\', '/', $module);
// Check if already loaded or load from file system
// ...
// ...
return $loadedModule;
}
So using Math\add would look like this:
require('Math\add')('require')(1, 2)
// ^- dependency loader function
Of course this does not look very nice so the build process would generate the namespaces and automatically fill in the require calls:
namespace Math {
function add(...$args) {
return require(__FUNCTION__)('require')(...$args);
}
/* Or constants ... */
const MAGIC = 0xDEADBEEF;
}
Constants could be require'd in the same fashion as functions:
require('Math\MAGIC') // 0xDEADBEEF
// or through the generated namespace
Math\MAGIC // 0xDEADBEEF
The benefits I see:
- Flexible structure (namespaces are generated automatically).
- Easily mockable and testable.
- Clear dependencies (dependencies are always
require
'd)
But I can also see the danger of having too many variables because of the way dependencies are managed. Also I'm not too sure about the performance.
I have never seen such an architecture and I'm curious what others think of my concept.
require
is a reserved word in PHP.