Chainable methods
A method is a transformation applied to a value with .name(args):
$engine->evaluate('trigger.user.name.trim().upper()', [
'trigger' => ['user' => ['name' => ' ada ']],
]);
// → "ADA"
Each method takes the value on its left, does something with it, and returns a new value that the next method in the chain operates on. There is no mutation of the context.
Methods are matched by the value's type
The same method name can behave differently depending on what it's called
on. count() on a string returns its length; count() on an array
returns its number of elements. reverse() reverses a string's
characters or an array's order. The engine picks the implementation
registered for the runtime type of the value:
| Value | Type used for lookup |
|---|---|
"hello" | string |
42 | int |
3.14 | double |
true / false | bool |
['a', 'b'] | array |
| a date (see below) | Carbon\CarbonImmutable |
If no method is registered for that specific type, the engine falls back
to methods registered for any — default() and
in(), which work on every
value. (Type casts and guards like string(), isset(), and if() are
functions, not methods.)
Calling a method that exists but not for this type raises
TypeMismatchException; calling a name that
isn't registered at all raises UnknownMethodException.
The full catalogue
See the methods reference for every built-in method grouped by type:
- String methods — case, trimming, slicing, casing conventions,
split() - Array methods —
first(),last(),sum(),pluck(),join(),groupBy(), plus the list operations - Number methods — rounding, clamping, formatting, arithmetic
- Date methods — add/subtract units, comparisons, diffs, formatting, component accessors
- Any-value methods —
default()andin(), valid on any value
Working with dates
Dates are the one type you don't pass in directly — you produce one from a string or "now", then chain date methods onto it.
Produce a date with the date(), now(), or today()
functions — date() parses a
value, the other two give you the current moment:
// From a value in context
$engine->evaluate('date(trigger.order.dueDate).addDays(3).format("Y-m-d")', [
'trigger' => ['order' => ['dueDate' => '2026-01-01']],
]);
// → "2026-01-04"
// From now
$engine->evaluate('now().addDays(5).format("Y-m-d")', []);
// A common workflow check: "is the due date within the next 3 days?"
$engine->evaluate('date(trigger.order.dueDate).isBefore(now().addDays(3))', $context);
// → true / false
When called without a format argument, date(), now(), and
today() return a chainable date object. When called with a format
string, they return a plain formatted string for simple, non-chained
use:
$engine->evaluate('now("Y-m-d")', []);
// → "2026-08-31" (a string, chain ends here)
Date methods that compare or diff against another date (isBefore(),
diffInDays(), isSame()) accept either another date object or a plain
date string, which they parse automatically.
An unparseable date string raises
EvaluatorException.