morningtrain/php-loader
A lightweight PHP loader for Morningtrain projects that simplifies autoloading and class resolution. It offers a simple, framework-friendly API to register loaders, resolve namespaces, and keep bootstrapping clean. Ideal for Laravel apps needing flexible, explicit loading without extra overhead.
Architecture fit
morningtrain/php-loader is a single-purpose utility: given a path, require/include a PHP file and optionally instantiate a class from it. In a Laravel codebase, this is a layer that Laravel already owns at three levels: Composer's PSR-4 autoloader handles class-level loading, the service container handles instantiation and dependency resolution, and ServiceProvider::load*From() handles registration of migrations, routes, views, translations, and commands. A TPM should treat the package as non-core, adjunct tooling — appropriate only in narrow cases where files genuinely cannot be autoloaded: user-supplied or tenant-supplied PHP drop-ins, a runtime plugin/module directory scanned from disk, legacy code being progressively migrated, or a package that must work in both Laravel and non-framework contexts (Morning Train publishes Laravel and WordPress-adjacent tooling).
It is not a substitute for autoloading, and any proposal to use it for application-domain class resolution should be rejected. Its only defensible architectural role is as a thin seam over filesystem-driven inclusion, ideally hidden behind an in-house interface.
Integration feasibility
Mechanically trivial: MIT-licensed, no evident dependency chain, likely a handful of files. composer require is a five-minute spike. The gating factors are not technical difficulty but confidence:
Because the surface is small, the source itself is the due-diligence artefact. A senior engineer can read the entire package in under an hour and make a definitive judgement; that is the cheapest possible risk reduction and should be a prerequisite.
Technical risk
requires it is a code-execution primitive. If a path or class name ever derives from request input, user content, or a database row, this becomes a remote-code-execution vector. The loader must be constrained to a fixed allowlist of directories with canonicalised paths.E_COMPILE_ERROR/E_ERROR, not catchable exceptions, unless the loader converts them — verify.Key questions
require or require_once, and how does it prevent double-inclusion / class redeclaration?false, or fatal?Stack fit
Poor fit for standard Laravel application code; acceptable fit for module/plugin discovery, tenant-scoped extensions, or a legacy bridge layer. If the codebase is conventional Laravel, the honest recommendation is: do not adopt, replicate the ~30 lines you need internally with tests and a clear contract.
Migration path
Adopt behind an adapter, never directly:
FileLoader interface (load(string $path): void, loadClass(string $path, string $class): object) in your domain layer.morningtrain/php-loader — or, preferably, over native require_once + new $class() if the package's added value is just error normalisation.composer.json and enable Dependabot/Renovate so a hypothetical upstream release is reviewed, not silently pulled.This keeps the swap cost near zero if the package is abandoned — which, on the evidence, is the base case.
Compatibility
Verify PHP constraint against your runtime, and confirm the loader does not rely on framework globals (app(), base_path()) if you intend to use it in queue workers or CLI contexts. Check for conflicts with OPcache settings and with composer dump-autoload --optimize (classmap-authoritative mode will not interfere, but any dynamic class name resolution should be validated under it).
Sequencing
Maintenance
You will own this. No evidence of a security policy, release cadence, or dependency-update automation. Budget for a periodic manual review — cheap given the size, but non-zero, and it must be scheduled or it will not happen. Consider vendoring or forking into an internal namespace to make ownership explicit.
Support
Effectively none. GitHub issues on a 1-star repository should be assumed unanswered. Internal documentation is mandatory: what the loader does, where it may be called from, and the allowlisted roots.
Scaling
Runtime cost is negligible in absolute terms, but the model is eager, not lazy. Loading N files on every request scales linearly where Composer's autoloader scales with classes actually used. Keep usage bounded and out of hot paths; avoid it in middleware or per-request bootstrapping.
Failure modes
Each of these needs a named owner and a mitigation before production: path allowlist, require_once semantics confirmed, structured logging, and a documented "trusted input only" rule.
Ramp-up
Minimal — an hour for a mid-level engineer to understand the API. The real onboarding cost is policy, not code: teams must know when not to reach for it. Without that, it becomes a convenient bypass around the container and autoloader, and the codebase drifts toward filesystem-coupled loading that is harder to test, refactor, and statically analyse. Document the exception, not just the tool.
How can I help you explore Laravel packages today?