Namespaces and modules are orthogonal, you can support both like Typescript.
Your solution works, but unfortunately not something that has any community support. I proposed something similar a year ago but use classes instead because classes seems to be the internal building block in PHP.
For both our solutions is would relatively easy to add a shim to older PHP versions.
module.php
<?php
return new class {
public const MY_CONST = 47;
private const MY_PRIVATE_CONST = 127;
// with PHP 8.1 you also have readonly properties
public string $myPublic = 'foo';
private int $myPrivate = 17;
public function helloWorld(string $name): void
{
echo "Hello, World {$name}!";
}
};
main.php <?php
final class ModuleException extends Exception {
}
function module(string $name): object
{
static $modules = [];
if (isset($modules[$name])) {
return $modules[$name];
}
try {
$module = @require $name;
} catch (Error $error) {
throw new ModuleException("No such module {$name}", 0, $error);
}
if (!is_object($module)) {
throw new ModuleException("Module {$name} is not an object");
}
$modules[$name] = $module;
return $module;
}
$my = module('module.php');
$my->helloWorld('Module system');
$other = module('module.php');
assert($my === $other);
https://news.ycombinator.com/item?id=30242974