https://github.com/eventjet/ausdruck
A small generic expression engine for PHP
https://github.com/eventjet/ausdruck
expressionengine hacktoberfest php
Last synced: about 1 month ago
JSON representation
A small generic expression engine for PHP
- Host: GitHub
- URL: https://github.com/eventjet/ausdruck
- Owner: eventjet
- License: mit
- Created: 2023-10-05T10:20:10.000Z (over 2 years ago)
- Default Branch: 0.2.x
- Last Pushed: 2025-10-16T05:01:31.000Z (4 months ago)
- Last Synced: 2025-10-17T07:45:38.297Z (4 months ago)
- Topics: expressionengine, hacktoberfest, php
- Language: PHP
- Homepage:
- Size: 185 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Ausdruck
A small expression engine for PHP.
## Quick start
```
composer require eventjet/ausdruck
```
```php
use Eventjet\Ausdruck\Parser\ExpressionParser;
use Eventjet\Ausdruck\Parser\Types;
use Eventjet\Ausdruck\Type;
$expression = ExpressionParser::parse(
'joe:MyPersonType.name:string()',
new Types(['MyPersonType' => Type::listOf(Type::string())]),
);
$scope = new Scope(
// Passing values to the expression
['joe' => ['joe']],
// Custom function definitions
['name' => static fn (array $person): string => $person[0]],
);
$name = $expression->evaluate($scope);
assert($name === 'Joe');
```
## Documentation
### Accessing scope variables
Syntax: `varName:type`
Scope variables are passed from PHP when it calls `evaluate()` on the expression:
```php
use Eventjet\Ausdruck\Parser\ExpressionParser;
use Eventjet\Ausdruck\Scope;
$x = ExpressionParser::parse('foo:int')
->evaluate(new Scope(['foo' => 123]));
assert($x === 123);
```
#### Examples
`foo:int`, `foo:list`
See [Types](#types)
### Literals
- `123`: Integer
- `"foo"`: String
- `1.23`: Float
- `[1, myInt:int, 3]`: List of integers
- `["foo", myString:string, "bar"]`: List of strings
### Operators
Both operands must be of the same type.
| Operator | Description | Example | Note |
|----------|--------------|--------------------------|-------------------------------------------|
| `===` | Equality | `foo:string === "bar"` | |
| `-` | Subtraction | `foo:int - bar:int` | Operands must be of type `int` or `float` |
| `>` | Greater than | `foo:int > bar:int` | Operands must be of type `int` or `float` |
| `\|\|` | Logical OR | `foo:bool \|\| bar:bool` | Operands must be of type `bool` |
| && | Logical AND | `foo:bool && bar:bool` | Operands must be of type `bool` |
Where's the rest? We're implementing more as we need them.
### Types
The following types are supported:
- `int`: Integer
- `string`: String
- `bool`: Boolean
- `float`: Floating point number
- `list`: List of type T
- `map`: Map with key type K and value type V
- Any other type will be treated as an alias that you will have to provide when parsing the expression:
```php
use Eventjet\Ausdruck\Parser\ExpressionParser;
use Eventjet\Ausdruck\Type;
ExpressionParser::parse('foo:MyType', ['MyType' => Type::alias(Type::listOf(Type::string()))]);
```
### Functions
Syntax: `target.functionName:returnType(arg1, arg2, ...)`
The target can be any expression. It will be passed as the first argument to the function.
#### Example
`haystack:list.contains:bool(needle:string)`
#### Built-In Functions
| Function | Description | Example |
|------------|------------------------------------------------------------------------|--------------------------------------------------|
| `count` | Returns the number of elements in a list | `foo:list.count:int()` |
| `contains` | Returns whether a list contains a value | `foo:list.contains:bool("bar")` |
| `head` | Returns the first element of a list as an `Option` | `foo:list.head:Option()` |
| `isSome` | Takes an Option and returns whether it is `Some` | `foo:Option.isSome:bool()` |
| `map` | Returns a new list with the results of applying a [function](#lambdas) | `foo:list.map:list(\|i\| i:int - 2)` |
| `some` | Returns whether any element matches a [predicate](#lambdas) | `foo:list.some:bool(\|item\| item:int > 5)` |
| `substr` | Returns a substring of a string | `foo:string.substr:string(0, 5)` |
| `tail` | Returns all elements of a list except the first | `foo:list.tail:list()` |
| `take` | Returns the first n elements of a list | `foo:list.take:list(5)` |
| `unique` | Returns a list with duplicate elements removed | `foo:list.unique:list()` |
#### Custom Functions
You can pass custom functions along with the scope variables:
```php
use Eventjet\Ausdruck\Parser\ExpressionParser;use Eventjet\Ausdruck\Scope;
$scope = new Scope(
['foo' => 'My secret'],
['mask' => fn (string $str, string $mask) => str_repeat($mask, strlen($str))]
);
$result = ExpressionParser::parse('foo:string.mask("x")')->evaluate($scope);
assert($result === 'xxxxxxxxx');
```
The target of the function/method call (`foo:string` in the example above) will be passed as the first argument to the
function.
### Lambdas
Syntax: `|arg1, arg2, ... | expression`
To access an argument, you must specify its type, just like when accessing scope variables.
#### Example
`|item| item:int > 5`