Download the PHP package prohalexey/the-choice without Composer

On this page you can find all versions of the php package prohalexey/the-choice. 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 the-choice

TheChoice - Business Rule Engine

GitHub license

A powerful and flexible Business Rule Engine for PHP that allows you to separate business logic from your application code.

Features

This library helps you simplify the implementation of complex business rules such as:

Why use TheChoice? If you find yourself constantly modifying business conditions in your code, this library allows you to move those conditions to external configuration sources. You can even create a web interface to edit configurations dynamically.

Key Benefits

Table of Contents

Installation

Requirements: PHP 8.4+

Quick Start

Configuration Formats

JSON Configuration Example

YAML Configuration Example

Core Concepts

Node Types

Each node has a node property that describes its type and an optional description property for UI purposes.

Root Node

The root of the rules tree that maintains state and stores execution results. When the root node is omitted in the configuration, the library automatically wraps the top-level node in a root node (short syntax).

Properties:

Example:

Value Node

Returns a static value.

Properties:

Example:

Context Node

Executes callable objects and can modify the global state which is stored in the "Root" node.

Properties:

Example:

With Operator Example:

With Break Example:

Condition Node

Conditional logic with if-then-else structure.

Properties:

Example:

Collection Node

Contains multiple child nodes evaluated with a chosen logical strategy.

Properties:

Type reference:

Type Behaviour
and Returns true if all children return true. Short-circuits on the first false.
or Returns true if at least one child returns true. Short-circuits on the first true.
not Returns true only if none of the children return true (NOR). Short-circuits on the first true.
atLeast Returns true if at least count children return true. Requires count.
exactly Returns true if exactly count children return true. Requires count.

and Example:

not Example — passes when the user is not blacklisted:

atLeast Example — passes when at least 2 out of 3 conditions are met:

exactly Example — passes when exactly 2 conditions are met:

Switch Node

Evaluates a single context value once and routes execution to the first matching case branch. Similar to a switch/case statement in PHP, but the match criterion for each case can be any registered operator (not just equality).

Properties:

Cases are evaluated in order and the first match wins — subsequent cases are skipped.

Basic example (role-based dispatch):

Range dispatch with operators (first match wins):

JSON equivalent:

The then and default branches can be any node type — including context (with modifiers), condition, collection, or even a nested switch:

Built-in Operators

The following operators are available for context nodes:

Equality & comparison

String

Array

Type checks (no value field required)

Modifiers

Modifiers allow you to transform context values using mathematical expressions. Use the predefined $context variable in your expressions. Variables defined in the Root storage are also available.

For more information about calculations, see: https://github.com/chriskonnertz/string-calc

Storage Variable References

Any string starting with $ in an operator's value field (or a Switch case value) is resolved against Root storage at parse time. This lets you centralise thresholds and constants in one place and reference them across rules:

Works equally in Switch cases:

Resolution rules:

value in rule Storage contains Result
"$threshold" $threshold: 1000 operator receives 1000 (int)
"$role" $role: "admin" operator receives "admin" (string)
"$range" $range: [100, 500] operator receives [100, 500] (array)
"$unknown" (absent) operator receives "$unknown" (unchanged, no error)
"admin" (any) operator receives "admin" (literal, no resolution)
42 (any) operator receives 42 (non-string, no resolution)

Storage variables continue to work in modifiers exactly as before — the two features are independent and composable.

Rule Engine

RuleEngine evaluates multiple rules in a single run() call and returns an EngineReport with the result of each rule. Rules are executed in priority order (highest first).

A rule is considered fired when its result is neither null nor false.

Rule Registry

RuleRegistry is a named storage for rules with tags, version, and description metadata.

Rule Validator

RuleValidator performs static analysis of a rule tree before execution — it checks that all referenced contexts and operators are registered. Unknown names produce helpful "did you mean?" suggestions based on Levenshtein distance. This is useful in CI/CD pipelines to catch configuration errors before deployment.

Each ValidationError contains:

Pass empty arrays to skip validation of contexts or operators:

The ValidationException provides programmatic access to errors:

Evaluation Trace

RootProcessor::processWithTrace() runs the rule tree with tracing enabled. It returns an EvaluationTrace that contains both the final result and a detailed tree of every node visited during evaluation — which node was entered, what it returned, and the nesting structure.

Programmatic Trace Access

The trace is a tree of TraceEntry objects that you can walk programmatically:

Result Formatting

TraceEntry::toString() formats results in a human-readable way:

Result type Output
true TRUE
false FALSE
null null
int / float 42, 10.5
string "hello"
array [1,2,3]

Zero Overhead

Tracing has zero overhead when not used — the trace collector is only active during processWithTrace() and is automatically cleaned up afterwards. A normal process() call is completely unaffected.

Event System

RuleEngine accepts an optional PSR-14 EventDispatcherInterface and dispatches events at key points during evaluation. Events are purely observational — they do not alter rule results.

Available Events

Event class When dispatched
EngineRunBeforeEvent Before RuleEngine::run() processes any rules. Contains the sorted rule list.
EngineRunAfterEvent After all rules are processed. Contains EngineReport and elapsedMs.
RuleFiredEvent When a rule fires (result ≠ null and ≠ false). Contains RuleResult and elapsedMs.
RuleErrorEvent When a rule throws an exception. Contains the Throwable. Exception is re-thrown after dispatch.
ContextEvaluatedEvent After a context node is evaluated. Contains raw contextValue, operatorName, operatorValue, and result.
SwitchResolvedEvent After a switch node resolves. Contains contextValue, matchedCaseIndex (null = default), and result.

Using with RootProcessor directly

You can also attach the dispatcher to RootProcessor for standalone rule evaluation (without RuleEngine):

Events work alongside processWithTrace() — both systems are independent.

Zero Overhead

Events have zero overhead when no dispatcher is set — all dispatch calls are guarded by null checks.

Caching

CachedJsonBuilder and CachedYamlBuilder wrap the base builders with a transparent PSR-16 cache layer. The node tree is serialized after the first parse and deserialized on subsequent calls; the cache key is derived from the MD5 of the rule content, so the cache is automatically invalidated when the content changes.

CachedYamlBuilder works identically — just substitute CachedYamlBuilder for CachedJsonBuilder.

Container Integration

Built-in Container

TheChoice\Container is a small PSR-11 implementation bundled with the library. It is intended as a fallback for plain PHP projects without a DI container.

You can extend it at runtime without modifying library code:

You can also override built-in services (for example, a default resolver):

Using Symfony Container

The library is PSR-11 compatible and works with Symfony DI.

For complete Symfony examples (compact setup + explicit setup, JsonBuilder and YamlBuilder services), see:

Advanced Features

Custom Contexts

Create custom context classes by implementing ContextInterface and register them in the container:

Custom Operators

Create custom operators by extending AbstractOperator and registering the mapping via OperatorResolverInterface::register():

For Symfony examples (register() through DI calls), see docs/symfony.md.

Processor Cache Flushing

Each call to RootProcessor::process() automatically calls flush() on all registered processors, clearing any memoised results from the previous evaluation. This ensures correctness when the same processor instance is reused across multiple rule evaluations.

Examples and Testing

For more detailed examples and usage patterns, see the test files in the test/ directory, especially the container configuration examples.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Fluent Builder (DSL)

RuleBuilder provides a fluent PHP API for building rule trees programmatically — without writing JSON or YAML. All builders are immutable after construction and materialise their corresponding Node on the final ->build() call.

Always wrap the outermost builder in RuleBuilder::root() — its build() propagates the Root reference to every child node, which is required by modifiers, stoppable contexts, and the Switch processor.

Full Example

Static Entry Points

Method Returns Description
RuleBuilder::value(mixed $v) ValueBuilder Static value node
RuleBuilder::context(string $name) ContextBuilder Context node with optional operator
RuleBuilder::condition() ConditionBuilder if / then / else branching
RuleBuilder::collection(string $type) CollectionBuilder Multi-node collection
RuleBuilder::switch(string $ctx) SwitchBuilder Switch/case dispatch
RuleBuilder::root() RootBuilder Root node — always use as outermost

ContextBuilder

All 20 built-in operators are available as typed methods:

Additional configuration:

CollectionBuilder

Available types: and, or, not, atLeast (requires ->count(n)), exactly (requires ->count(n)).

SwitchBuilder

RootBuilder

Node Exporter

JsonNodeExporter and YamlNodeExporter convert a Node tree back to a JSON or YAML string (or file). The output is round-trip safe — re-parsing the exported content produces a tree with identical runtime behaviour.

Both exporters share the same NodeSerializer which builds the intermediate PHP array.

The NodeSerializer intermediate toArray() is public — use it directly when you need the raw PHP array:

Round-trip guarantee: all built-in node types (Root, Value, Context, Condition, Collection, SwitchNode) are fully supported. Optional fields (description, priority, params, modifiers, storage, break, else, default) are only emitted when they differ from the default value, keeping the output minimal.

License

This project is licensed under the MIT License - see the LICENSE file for details.


All versions of the-choice with dependencies

PHP Build Version
Package Version
Requires php Version >=8.4
ext-json Version *
ext-mbstring Version *
chriskonnertz/string-calc Version ^2.0
psr/container Version ^2.0.0
psr/event-dispatcher Version ^1.0
psr/simple-cache Version ^3.0
symfony/yaml Version ^7.3
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 prohalexey/the-choice contains the following files

Loading the files please wait ...