Download the PHP package liquidrazor/registry-loader without Composer

On this page you can find all versions of the php package liquidrazor/registry-loader. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package registry-loader

LiquidRazor Framework - RegistryLoader

Overview

The RegistryLoader is the bridge between class discovery and a compiled dependency registry.

It exists to transform the output of:

into normalized descriptor definitions consumable by:

In practical terms, the RegistryLoader is responsible for turning a discovered class collection into a strict, deterministic, compile-time validated service definition graph.

It is not a container on its own. It is not a runtime resolver. It is not an object instantiator. It is not responsible for service lifetime handling at runtime.

Those concerns belong to DIRegistry.

The RegistryLoader is the compile-time transformation layer that prepares data for DIRegistry.


Position in the LiquidRazor pipeline

The intended pipeline is:

Responsibility split

FileLocator

Responsible only for deterministic filesystem scanning.

It discovers relevant PHP files according to configured roots and project conventions. It does not parse classes semantically and does not perform DI logic.

ClassLocator

Responsible for mapping files to expected classes and validating class-level structure.

It uses FileLocator output, applies PSR-4 mapping rules, validates FQCN expectations, and produces a reliable class collection. It does not register services and does not perform dependency-injection decisions.

RegistryLoader

Responsible for transforming discovered classes into normalized descriptor definitions.

It applies:

and outputs a descriptor-definition graph ready to be compiled into DIRegistry.

DIRegistry

Responsible for the actual dependency-injection runtime model.

It owns:

The RegistryLoader must never duplicate these responsibilities.


Core purpose

The RegistryLoader answers one question:

Given a validated class collection, which classes should become services, under which contracts, with which lifecycle, using which scalar values, and under which compile-time rules?

Its output must be:

The entire philosophy is simple:


Design principles

1. Compile-time first

All service definition decisions must be made before runtime.

The RegistryLoader is part of the compile phase of the framework. It exists so that runtime behavior is reduced to resolution and instantiation, not discovery and interpretation.

2. Deterministic behavior

The same codebase and configuration must always produce the same descriptor graph. No load-order tricks. No priority roulette. No best-effort inference.

3. Explicit over clever

Conventions are allowed only where they are trivial and safe. When a decision becomes non-trivial, the system must require attributes or config.

4. Fail hard on ambiguity

If the system cannot know the correct answer with certainty, compilation must fail. Warnings are not enough for architecture-level ambiguity.

5. Runtime must stay boring

By the time DIRegistry receives the normalized definitions, the meaningful architectural decisions are already made. Runtime should not negotiate with the environment or attempt to infer service topology.


Input sources

The RegistryLoader operates on three input categories.

1. Class collection

Produced by ClassLocator. This is the authoritative discovered set of classes eligible for further evaluation.

The RegistryLoader does not scan the filesystem directly. It consumes the output of the locator layer.

2. Attributes

Attributes provide explicit metadata directly on classes or constructor parameters. They refine or override convention-based inference.

Attributes are not mandatory for the common case. They are used where explicit control is needed.

3. Explicit configuration

Explicit configuration has the highest precedence. It exists to:

RegistryLoader delegates config file resolution, format handling, parsing, layered merge behavior, and environment interpolation to liquidrazor/config-loader. Its own responsibility starts after config has already been loaded into normalized arrays.


Precedence model

The precedence order is fixed:

  1. explicit configuration
  2. attributes
  3. convention

This rule applies across all supported metadata categories.

Convention

Convention provides the baseline candidate definition.

Attributes

Attributes refine or replace convention-derived values.

Configuration

Configuration is authoritative and overrides both attributes and convention.

There is no “last loaded wins” behavior. There is no scanner-order dependency. There is no merge order determined by accident.

Configuration files are loaded through liquidrazor/config-loader in YAML mode. RegistryLoader does not parse YAML or JSON itself.


Service candidate evaluation

Every discovered class from ClassLocator is evaluated as a possible service candidate.

A class is considered eligible for convention-based evaluation only if all of the following are true:

Root-aware convention behavior

The project layout strongly influences service candidacy.

Convention-based loading should apply by default to:

Convention-based loading should not apply blindly to:

This is intentional.

include/ is expected to contain contracts, types, enums, exceptions, descriptors, value objects, and other definition-level structures that are not automatically runtime services.

Classes inside include/ may still become services through explicit attributes or configuration, but they should not be loaded by naive convention.


Hybrid loading model

The RegistryLoader uses a hybrid model:

This gives the framework both low boilerplate and strict control.

Why hybrid is the correct model

Pure convention is too implicit for non-trivial systems. Pure attributes are too verbose for ordinary services. The hybrid model allows the common case to remain clean while still forcing explicitness where necessary.


Baseline convention definition

For each valid service candidate, convention produces an initial descriptor-definition candidate.

Typical baseline values include:

Default identifier

The default identifier is the fully qualified class name.

This ensures uniqueness and removes the need for string aliases or arbitrary service names.

Default construction strategy

The default construction strategy is constructor-based instantiation.

Factory-based construction is never inferred by convention in version 1. Factories must be explicit.

Source metadata

The loader should preserve enough source information to generate useful compile-time errors. That usually includes:


Lifecycle inference rules

Lifecycle inference is intentionally strict and architecture-aware.

Core lifecycle philosophy

Shared services are safe only when architecture makes them safe. Long-lived workers and future fork-based models make careless singleton defaults dangerous.

Therefore, the framework does not treat singleton as the universal default.

Default lifecycle rules

Constructor-based class services

Factory-based services

Pooled services

Scoped services

Why readonly matters

Readonly classes provide a language-level architectural signal that the service is intended to be immutable after construction. That makes them viable candidates for safe sharing.

Non-readonly classes are assumed mutable and therefore isolated by default.

Important limitations

Readonly is not absolute purity. A readonly class may still hold references to mutable objects. Therefore:

The framework still allows explicit lifecycle overrides where necessary.


Contract inference rules

Contract inference is one of the most sensitive parts of the system. The framework intentionally avoids magic here.

Core principles

No parent class inference

Inheritance is treated as implementation detail, not as DI contract surface. This avoids accidental exposure of scaffolding, internal hierarchies, and long inheritance chains as injectable contracts.

Convention-based contract inference

A class may be auto-exposed under a contract only if:

Outcomes

Zero interfaces

No inferred contract. The class remains resolvable only by concrete class path.

Exactly one interface

That interface may be inferred as the contract, provided it matches allowed contract roots.

More than one interface

No contract is inferred. Explicit declaration is required.

Allowed contract roots

Convention-based contract inference should be limited to configured contract namespaces or roots. This avoids exposing technical or incidental interfaces such as generic PHP or support-level interfaces.

A typical project-level convention is to treat interfaces under a contract namespace such as ...\Contract\ as eligible for inference.

Multiple implementations of the same contract

If more than one service exposes the same contract, resolution is valid only if exactly one implementation is explicitly marked as the default.

Valid cases

Invalid cases

All invalid cases must fail at compile time.

No priority-based default selection

Numeric priority is intentionally excluded from default contract selection. The framework does not guess which implementation should win.

If multiple candidates exist, the developer must declare the intended default explicitly.

Priority may exist later for ordered collections or aggregation scenarios, but not for ordinary single-contract default resolution.


Scalar binding rules

Scalar values are compile-time concerns. They must never remain unresolved until runtime.

Core scalar philosophy

Scalar dependencies are too ambiguous to autowire safely. A string, integer, float, or boolean carries no architectural intent by itself.

Therefore, scalar resolution must be deterministic and complete during compilation.

Scalar resolution order

For every scalar constructor dependency, the RegistryLoader applies the following precedence order:

  1. explicit attribute override
  2. explicit configuration binding
  3. exact environment-variable inference
  4. constructor default value
  5. hard compile-time failure

Compile-time only

Scalars must always be resolved during compile time.

This guarantees:

Default environment-variable inference

If no explicit scalar binding exists, the loader may attempt exact env inference.

The default convention is:

This convention must be exact and deterministic. There is no fuzzy matching based only on parameter names such as HOST, PORT, or DSN.

Constructor defaults

If no attribute, config binding, or env value exists, the loader may use the constructor’s declared default value.

Failure rule

If a required scalar cannot be resolved after all resolution stages, compilation must fail.

The framework never injects null silently and never falls back to guesswork.


Attribute model

The attribute surface should remain intentionally small. Attributes are used to express meaningful architectural decisions, not to recreate an annotation-heavy mini language.

Recommended attribute surface

#[Service(...)]

Used to define or override service-level metadata.

Supported concerns may include:

#[Scalar(...)]

Used on constructor parameters to override scalar binding metadata.

Typical use:

#[IgnoreService]

Used to exclude a discovered class from service registration.

Attribute philosophy

Attributes should:

Attributes should not become a general-purpose configuration language.


Factory handling

Factories are supported, but they are intentionally explicit.

Rules

Why factories are explicit-only

Factory methods are a common source of hidden state and side effects. Convention-based factory discovery would introduce ambiguity and surprise. The framework chooses predictability over convenience.


Error model

Errors are a first-class part of the design. In a strict compile-time system, error messages are effectively part of the user interface.

Error principles

Errors must be:

Example failure categories

Example error style

Good errors should look like:

The goal is immediate diagnosis, not generic exception noise.


Compile-time validation expectations

The RegistryLoader should validate the full descriptor graph before handing it to DIRegistry.

Validation should include at least:

The loader should fail before runtime whenever architectural ambiguity or invalid state exists.


Loading into DIRegistry

The RegistryLoader does not stop at producing abstract metadata in the void. Its purpose is to produce normalized descriptor definitions and then hand them into DIRegistry for compilation and registry population.

That means the loading flow is not merely:

It must continue with the actual transfer into the DI system.

Effective loading flow

The full compile pipeline is:

What “loading into the registry” actually means

The RegistryLoader must convert its final internal representation into the exact normalized definition shape expected by DIRegistry.

It then passes that complete normalized definition set to RegistryCompiler.

RegistryCompiler is responsible for:

So the RegistryLoader does not manually mutate runtime registry state entry by entry like an ad-hoc service bag. It prepares the full descriptor definition graph and then loads the graph into DIRegistry through the compiler boundary.

Compiler boundary as the official integration point

The integration point between RegistryLoader and DIRegistry is the compiler boundary.

That boundary exists for a reason:

This separation keeps both libraries honest.

The RegistryLoader must therefore output definitions in the canonical format required by DIRegistry and invoke compilation explicitly.

Output of the RegistryLoader

The practical output of the RegistryLoader should be one of the following, depending on API style:

Option A: compiled registry as final product

The RegistryLoader returns a compiled DIRegistry instance, having internally:

  1. collected classes
  2. built normalized definitions
  3. passed them into RegistryCompiler
  4. returned the compiled registry

This is the most ergonomic option for framework bootstrapping.

Option B: normalized definitions as an intermediate product

The RegistryLoader returns the normalized definition set, and a higher bootstrap layer passes it to RegistryCompiler.

This is more explicit, but also more fragmented.

Recommended approach

For framework use, the preferred behavior is:

That way, “loading” actually means loading, not merely preparing data and hoping something else remembers to finish the job.

Why this matters

Without this final step, the RegistryLoader would be incomplete. It would only be a descriptor-definition builder, not the actual bridge from class discovery into a usable compiled dependency registry.

The whole point of the component is to connect:

with the actual compiled registry consumed later by:

So the final act of the RegistryLoader is:

produce normalized definitions, compile them through DIRegistry, and hand back a usable compiled registry.

Runtime boundary

The RegistryLoader ends where compiled DIRegistry begins.

Once normalized descriptor definitions are produced, validated, and compiled, responsibility transfers to DIRegistry for:

This boundary must remain clean.

The RegistryLoader must never become:

Its job is to:

  1. transform class discovery into normalized definitions
  2. resolve compile-time metadata
  3. validate the graph
  4. compile the graph into DIRegistry
  5. stop

Version 1 scope

Version 1 should remain intentionally focused.

Included in version 1

Deliberately excluded from version 1

The system should first be correct, explicit, and stable. Additional features should be added only if they preserve determinism and strictness.


Summary

The RegistryLoader is the compile-time transformation layer between class discovery and dependency-injection runtime.

It exists to produce a normalized, validated descriptor-definition graph from:

Its design is based on a few non-negotiable rules:

The result is a DI preparation layer that actively enforces architecture rather than merely accommodating it.

That is the intended role of the RegistryLoader inside the LiquidRazor Framework.


All versions of registry-loader with dependencies

PHP Build Version
Package Version
Requires php Version >=8.3
liquidrazor/class-locator Version ^0.1
liquidrazor/config-loader Version ^0.1
liquidrazor/diregistry Version ^0.1
liquidrazor/file-locator Version ^0.1
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package liquidrazor/registry-loader contains the following files

Loading the files please wait ...