This repository contains a PHP implementation of the Common Expression Language (CEL).
- Documentation
- Example
- Specification Compliance
- License
- Security Policy
- Code of Conduct
- Contributing
- Development
- Getting Started - Installation, basic usage, and core concepts
- Standard Extensions Reference - Available functions and operators
- Caching - Improve performance with caching
- Custom Functions - Extend CEL with your own functions
- Custom Operators - Add custom binary and unary operators
- Value Resolvers - Support custom PHP types in CEL
use Cel;
// Simple expression evaluation
$result = Cel\evaluate('1 + 2');
echo $result->getRawValue(); // Output: 3
// With variables
$result = Cel\evaluate(
'user.age >= 18',
['user' => ['age' => 25]]
);
echo $result->getRawValue(); // Output: trueuse Cel;
const EXPRESSION = <<<CEL
account.balance >= transaction.withdrawal
|| (account.overdraftProtection
&& account.overdraftLimit >= transaction.withdrawal - account.balance)
CEL;
// Create CEL instance
$cel = new Cel\CommonExpressionLanguage();
try {
// Parse the expression
$expression = $cel->parseString(EXPRESSION);
// Evaluate with context
$receipt = $cel->run($expression, [
'account' => [
'balance' => 500,
'overdraftProtection' => true,
'overdraftLimit' => 1000,
],
'transaction' => [
'withdrawal' => 700,
],
]);
echo $receipt->result->getRawValue(); // Output: true
} catch (Cel\Parser\Exception\UnexpectedTokenException $e) {
// Handle parsing errors
} catch (Cel\Exception\IncompatibleValueTypeException $e) {
// Handle type errors
} catch (Cel\Exception\EvaluationException $e) {
// Handle runtime errors
}use Cel;
use Symfony\Component\Cache\Adapter\ApcuAdapter;
use Symfony\Component\Cache\Psr16Cache;
// Create a cache instance
$cache = new Psr16Cache(new ApcuAdapter());
// Create CEL with caching enabled
$cel = Cel\CommonExpressionLanguage::cached($cache);
// Parsing and evaluation results will be cached automatically
$expression = $cel->parseString('1 + 2');
$receipt = $cel->run($expression);CEL-PHP is a production-ready, spec-compliant implementation of the Common Expression Language specification. All core language features, operators, macros, and standard library functions are fully implemented and tested.
-
Core Language
- All primitive types (int, uint, double, bool, string, bytes, null)
- Lists and Maps with full indexing support
- Duration and Timestamp types
- Field selection and indexing
- All operators (arithmetic, comparison, logical, membership)
- Conditional expressions (
? :) - Message construction
- String/bytes literals with complete escape sequence support
-
Macros
has(e.f)- Field presence checkinge.all(x, p)- Universal quantificatione.exists(x, p)- Existential quantificatione.exists_one(x, p)- Unique existencee.map(x, t)- Transformatione.filter(x, p)- Filtering
-
Standard Library
- Core functions (type conversions, size, type checking)
- String functions (contains, split, trim, case conversion, etc.)
- List functions (chunk, flatten, reverse, sort, etc.)
- Math functions (min, max, sum, mean, median, etc.)
- DateTime functions (timestamp, duration, accessors)
- Decimal support for arbitrary precision (optional extension)
-
Runtime & Tooling
- Tree-walking interpreter with full error tracking
- Expression optimization (constant folding, short-circuit evaluation, etc.)
- Extension system for custom functions and operators
- Value resolvers for custom PHP types
- Parse and evaluation result caching (PSR-16 compatible)
- Comprehensive exception handling with source span information
This implementation is ready for production use and meets all requirements for a 1.0.0 release. The following are potential future enhancements that could improve performance or developer experience, but are not required for the core functionality:
- Compile-time Type Checking: Static analysis of expressions before runtime (nice-to-have for catching errors earlier)
- Stack-based Interpreter: Alternative execution engine for improved performance (current tree-walking interpreter is sufficient for most use cases)
- Protocol Buffer Integration: Native protobuf support (manual message construction works well)
- Conformance Test Suite: Official CEL conformance tests (current test suite of 1,080+ tests provides comprehensive coverage)
Note: Performance benchmarks show that complex expressions evaluate in ~0.001 seconds in production environments, which is acceptable for the vast majority of use cases.
This project is licensed under the terms of the LICENSE file.
For information on security vulnerabilities and how to report them, please refer to our SECURITY.md.
Please review our CODE_OF_CONDUCT.md for expected behavior and guidelines for participation.
This project was developed by Carthage Software and is fully funded by Buhta.
We extend our sincere gratitude to Buhta for their generous support of open-source software. Their commitment to the PHP ecosystem makes projects like this possible.
We welcome contributions! Please see our CONTRIBUTING.md for details on how to get started.
This project uses just for task automation.
You can see all available commands by running just --list. Some common recipes include:
just install: Installs project dependencies.just test: Runs the test suite.just lint: Runs linting checks.just verify: Runs all checks (tests, linting, etc.) to ensure code quality. Always runjust verifybefore pushing any changes.
To get started with local development, you'll need to install just and typos.
Installing Just:
If you have Rust and Cargo installed, you can install just via Cargo:
cargo install justAlternatively, you can find other installation methods in the Just documentation.
Installing Typos:
If you have Rust and Cargo installed, you can install typos via Cargo:
cargo install typos-cliAfter installing just and typos, you can install the project dependencies and run verification checks:
just install
just verify