The current solution for code reuse (use longer class names to avoid clashes, we help you with syntactic sugar called "namespaces") is the wrong approach imo.
The current solution for code reuse (use longer class names to avoid clashes, we help you with syntactic sugar called "namespaces") is the wrong approach imo.
I'm curious as to why you consider autoloading over PSR-4 namespaces as insufficient.
If two packages I require depend on incompatible versions of some third package, there aren't any easy ways for me to resolve it.
This problem exists because of the global nature of PHP namespaces.
https://www.php.net/manual/en/language.namespaces.importing....
At least in the PHP I'm familiar with, nothing "happens" at `use` time; the first time you call a method on a class it autoloads. The autoloader is then what does the work of finding and requiring the file. No class, no autoloader.
A module system and less reliance on PSR the better. Why exactly does PSR still exist?
That's my problem with it. It should be focused on what's good for developers. Not what makes it easier to overengineer the next flavour of the month.
I will readily admit that 99% of my assertions are some variation of `$this->assertEquals()`
As a maker, I prefer a clean stack. So that its complexity does not slow me down. Workarounds make development slower and slower, the more it becomes a giant hairball of workarounds and workarounds around workarounds.
In Python and JavaScript, I don't need those workarounds. Would be awesome if PHP catches up.
You can in theory create modules with require.
module.php
<?php
return (function(){
$foo = function(){echo "hello from PHP";};
return [
"greet"=>$foo
];
})();
script.php <?php
$module = require('./module.php');
$module["greet"]();
But PHP namespaces and autoloading via composer ARE the community accepted way to handle namespacing. The ecosystem is so large developers aren't going to move to a different module system at that point. Especially when composer is the defacto package manager for PHP.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=30242974PHP dependencies are so intertwined that for projects that abuse and use more than a reasonable amount (aka their ability to invest time keeping them and the code using it up to date) the update process can become a nightmare of complexity.
Node's module system let you move each dependency at it's own pace. This is such a breath!
The problem is that when you only know of the solution of your ecosystem, it's hard to see the added value you miss out.
If you use a framework then try to write all your own code outside of the framework and pass in all needed framework data as arguments to your own classes/functions.
However, what I was speaking about is the version handling of (sometimes direct but mostly) indirect dependencies.
The domain of `composer why` and `composer why-not`.
One if the most speaking example I can think of is: if two libs depends on guzzle 5, then you can't update only one on a version that depends on guzzle 6: you must upgrade both at the same time. Each to an intercompatible lock on guzzle version.