PHPackages                             moto/autoload - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. moto/autoload

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

moto/autoload
=============

0.x-dev(9mo ago)50[1 issues](https://github.com/motophp/autoload/issues)MITPHPPHP ^8.4CI passing

Since Jul 31Pushed 9mo ago2 watchersCompare

[ Source](https://github.com/motophp/autoload)[ Packagist](https://packagist.org/packages/moto/autoload)[ RSS](/packages/moto-autoload/feed)WikiDiscussions 0.x Synced 1mo ago

READMEChangelogDependencies (4)Versions (1)Used By (0)

moto/autoload
=============

[](#motoautoload)

This project defines a name-to-file resolution algorithm for autoloaders that allows [more-than-one class per file](#more-than-one-class-per-file).

[![PDS Skeleton](https://camo.githubusercontent.com/50d01a5094afcc3a827c3cadaec43d23b2a256cb249f5fdd6e5ffdb53ea7971c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7064732d736b656c65746f6e2d626c75652e7376673f7374796c653d666c61742d737175617265)](https://github.com/php-pds/skeleton)[![PDS Composer Script Names](https://camo.githubusercontent.com/0c17df07fd0a51ad878f1de0d4c17ea8e460f2e96ce796c8cd58e6c96ed9c08d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7064732d636f6d706f7365722d2d7363726970742d2d6e616d65732d626c75653f7374796c653d666c61742d737175617265)](https://github.com/php-pds/composer-script-names)

Theory of Operation
-------------------

[](#theory-of-operation)

### One Class Per File

[](#one-class-per-file)

Historically, PHP class-to-file naming conventions have supported only one class per file.

#### Horde/PEAR

[](#hordepear)

In the pre-namespacing versions of PHP, the original [Horde/PEAR resolution logic](https://pear.php.net/manual/en/standards.naming.php) converted underscores to directory separators to generate a file path:

```
Foo_Bar_Baz_Dib     => /classes/Foo/Bar/Baz/Dib.php
Foo_Bar_Baz_Dib_Zim => /classes/Foo/Bar/Baz/Dib/Zim.php

```

#### PSR-0

[](#psr-0)

[PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md) modified this logic to recognized the formal namespaces introduced in PHP 5.3, so that ...

1. namespace separators were converted to directory separators, and
2. underscores only in the terminating class name portion were converted to directory separators:

```
Foo_Bar\Baz\Dib     => /classes/Foo_Bar/Baz/Dib.php
Foo_Bar\Baz\Dib_Zim => /classes/Foo_Bar/Baz/Dib/Zim.php

```

#### PSR-4

[](#psr-4)

[PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md) modified PSR-0 so that ...

1. underscores in the terminating class name portion would no longer be converted to directory separators, and
2. a namespace prefix could be mapped to a directory prefix:

```
/**
 * 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_Zim.php

```

### More-Than-One Class Per File

[](#more-than-one-class-per-file)

The Moto name-to-file [resolution algorithm](#resolution-algorithm) modifies this even further, so 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.

Resolution Algorithm
--------------------

[](#resolution-algorithm)

Given ...

- a `namespace-prefix` of a non-empty namespace (including the rightmost namespace separator) or an empty string (indicating the global namespace), and
- an absolute `directory-prefix` for the `namespace-prefix` (including the rightmost directory separator)

... the following algorithm resolves a `fully-qualified-name` to an `absolute-file-path` or to `null`:

1. If the `fully-qualified-name` does not begin with the `namespace-prefix`, the `fully-qualified-name` resolves to `null`.
2. Otherwise, set the `qualified-name` by capturing all characters after the `namespace-prefix`.
3. If the `qualified-name` contains a namespace separator ...

    A. Set the `partial-namespace` by capturing all characters up to and including the rightmost namespace separator, and set the `partial-name` by capturing all characters after the rightmost namespace separator.

    B. Otherwise, set the `partial-namespace` to an empty string, and set the `partial-name` to the `qualified-name`.
4. If the `partial-name` contains an underscore, remove the first underscore and all characters thereafter.
5. If the `partial-name` is empty, the `fully-qualified-name` resolves to `null`.
6. Otherwise, set the `partial-directory` by converting each namespace separator in the `partial-namespace` to a `DIRECTORY_SEPARATOR`.
7. Set the `absolute-file-path` by concatenating the `directory-prefix`, `partial-directory`, `partial-name`, and a `filename-suffix` (typically `.php`).
8. If the `absolute-file-path` exists, the `fully-qualified-name` resolves to the `absolute-file-path`; otherwise, it resolves to `null`.

Cf. the [reference implementation](./src/Loader.php) `resolutionAlgotrithm()` method for an example.

Implications
------------

[](#implications)

- Directory names with underscores WILL be resolvable.
- Base file names with underscores WILL NOT be resolvable.
- PSR-4 mapped classes *without underscores* are Moto-compatible.
- The `partial-name` itself does not have to exist at the `absolute-file-path`; that is, the file might contain only underscore-suffixed names:

    ```
    // Foo_Bar\Baz => /vendor/foo-bar/baz/src/Dib.php
    namespace Foo_Bar\Baz;

    // no Dib {} class

    class Dib_Zim {}

    class Dib_Gir {}

    class Dib_Irk {}
    ```
- 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() {}
    ```

---

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance52

Moderate activity, may be stable

Popularity5

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

291d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/25754?v=4)[Paul M. Jones](/maintainers/pmjones)[@pmjones](https://github.com/pmjones)

---

Top Contributors

[![pmjones](https://avatars.githubusercontent.com/u/25754?v=4)](https://github.com/pmjones "pmjones (6 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/moto-autoload/health.svg)

```
[![Health](https://phpackages.com/badges/moto-autoload/health.svg)](https://phpackages.com/packages/moto-autoload)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
