More-Than-One Class Per File
In this PHP internals message we read:
I have participated in some internals discussions that point out a fact from the other direction: PHP makes no imposition about file structure. 1-class-per-file is strictly a PSR-4 implementation of a custom autoloader which we have gotten used to for so long. I would really love to be able to declare small related classes/interfaces in a single file ...
There is something to be said for more-than-one class per file, and after a few evenings of tinkering, I can now present the moto/autoload package.
The Moto name-to-file resolution algorithm is an ideological descendant from Horde/PEAR through PSR-0 and PSR-4, with the latest evolution being that everything after an underscore in the terminating class name portion is ignored:
/**
* Foo_Bar\Baz\ maps to /classes/foo-bar/baz/src/
*/
Foo_Bar\Baz\Dib => /classes/foo-bar/baz/src/Dib.php
Foo_Bar\Baz\Dib_Zim => /classes/foo-bar/baz/src/Dib.php
Foo_Bar\Baz\Dib_Gir => /classes/foo-bar/baz/src/Dib.php
Foo_Bar\Baz\Dib_Irk => /classes/foo-bar/baz/src/Dib.php
This means the Dib.php
file can contain any number of underscore-suffixed classes so long as they are prefixed with Dib
...
// /classes/foo-bar/src/Baz/Dib.php
namespace Foo_Bar/Baz;
class Dib { }
class Dib_Zim { }
class Dib_Gir { }
class Dib_Irk { }
... and a Moto-compliant resolver will find the correct file for that class.
And if function autoloading becomes supported by PHP, the Moto name-to-file resolution algorithm can support multiple functions per file:
// Foo_Bar\Baz => /vendor/foo-bar/baz/src/dib.php
namespace Foo_Bar\Baz;
function dib() {}
function dib_zim() {}
function dib_gir() {}
function dib_irk() {}
I'm soliciting feedback on this approach, so please post your comments and concerns at Github as issues and pull requests.