Text-Based DSL
Ruler supports a Wirefilter-style text-based DSL for creating rules using natural, readable syntax. This complements the fluent PHP API—both produce identical results.
Quick Start
Section titled “Quick Start”use Cline\Ruler\DSL\Wirefilter\StringRuleBuilder;use Cline\Ruler\Core\Context;
$srb = new StringRuleBuilder;
// Create a rule from text$rule = $srb->parse('age >= 18 and country == "US"');
// Evaluate with context$context = new Context(['age' => 25, 'country' => 'US']);$result = $rule->evaluate($context); // true
// Add action callback$rule = $srb->parseWithAction( 'price + shipping > 100', fn() => applyFreeShipping());$rule->execute($context);Syntax Reference
Section titled “Syntax Reference”Comparison Operators
Section titled “Comparison Operators”age > 18 // Greater thanage >= 21 // Greater than or equalage < 65 // Less thanage <= 64 // Less than or equalstatus == "active" // Loose equalitystatus != "inactive" // Loose inequalityrole === "admin" // Strict equalityrole !== "guest" // Strict inequalitycountry in ["US", "CA"] // Array membershiprole notIn ["banned"] // Array exclusionLogical Operators
Section titled “Logical Operators”age >= 18 and country == "US" // ANDage >= 21 or country == "US" // ORnot (age < 18) // NOT(age >= 18 and country == "US") or age >= 21 // Parentheses for groupingMathematical Operators
Section titled “Mathematical Operators”price + shipping > 100 // Additiontotal - discount < 500 // Subtractionquantity * price >= 1000 // Multiplicationtotal / items > 10 // Divisionvalue % 2 == 0 // ModuloString Operators
Section titled “String Operators”Function-style syntax for string operations:
contains(email, "@example.com") // String containsstartsWith(username, "admin_") // Starts withendsWith(filename, ".pdf") // Ends withmatches(phone, "^\\d{3}-\\d{4}$") // Regex matchComplex Examples
Section titled “Complex Examples”User Eligibility Check
Section titled “User Eligibility Check”(user.age >= 18 and user.country in ["US", "CA"]) or(user.isVerified == true and user.role != "guest")Pricing Logic
Section titled “Pricing Logic”(price + shipping > 100 and user.isPremium == true) or(price > 200)Combined Conditions
Section titled “Combined Conditions”user.age >= 18 andcountry == "US" andnot (status == "banned") and(subscription == "premium" or purchases > 10)DSL vs Fluent PHP
Section titled “DSL vs Fluent PHP”Both syntaxes produce identical Operator trees:
DSL Syntax:
$srb = new StringRuleBuilder;$rule = $srb->parse('age >= 18 and country == "US"');Fluent PHP:
$rb = new RuleBuilder;$rule = $rb->create( $rb->logicalAnd( $rb['age']->greaterThanOrEqualTo(18), $rb['country']->equalTo('US') ));Operator Precedence
Section titled “Operator Precedence”From highest to lowest:
- Parentheses —
() - Unary operators —
not,- - Exponentiation —
** - Multiplicative —
*,/,% - Additive —
+,- - Comparison —
>,>=,<,<= - Equality —
==,!=,===,!== - Logical AND —
and - Logical OR —
or
Use parentheses for explicit grouping when precedence is unclear.
Variables and Properties
Section titled “Variables and Properties”Simple names or dot-notation for nested properties:
age // Simple variableuser.age // Nested propertyhttp.request.uri.path // Deeply nestedType Inference
Section titled “Type Inference”The DSL automatically infers types:
age > 18 // Numericstatus == "active" // Stringtags in ["urgent"] // Arrayenabled == true // Booleancount == null // NullWhen to Use DSL vs Fluent PHP
Section titled “When to Use DSL vs Fluent PHP”Use DSL when:
- Rules are stored as text (database, config files)
- Non-developers need to read/understand rules
- Brevity is important for complex expressions
- Rules are generated from UI forms
Use Fluent PHP when:
- IDE autocomplete is important
- Type safety at the code level is critical
- Rules are built programmatically
- PHP code generation is your workflow
Both approaches coexist seamlessly.