Zum Hauptinhalt springen
YouTube Security VideosMicrosoft Developer: Why AI agents Cost So Much(20.10.2026 um 09:00 Uhr)
••
Windows Tipps & SecurityWindows Sandbox: So testen Sie unsichere Dateien gefahrlos(20.10.2026 um 08:00 Uhr)
•••
Windows Tipps & SecurityDriverMax(20.10.2026 um 10:00 Uhr)
••••
Podcasts & Audio BriefingsFraunhofer IEM: Geld ohne Arbeit: Macht KI uns alle reich? | OUTATIME #44(20.10.2026 um 06:00 Uhr)
•
YouTube Security VideosMicrosoft Developer: Why AI agents Cost So Much(20.10.2026 um 09:00 Uhr)
••
Windows Tipps & SecurityWindows Sandbox: So testen Sie unsichere Dateien gefahrlos(20.10.2026 um 08:00 Uhr)
•••
Windows Tipps & SecurityDriverMax(20.10.2026 um 10:00 Uhr)
••••
Podcasts & Audio BriefingsFraunhofer IEM: Geld ohne Arbeit: Macht KI uns alle reich? | OUTATIME #44(20.10.2026 um 06:00 Uhr)
•
Intelligence View
⚡ tsecurity.de Intelligence

How I stopped hardcoding business rules in PHP - and built a rule engine to fix it

Every PHP developer knows this situation: a client calls and says "I want free shipping for VIP customers on weekends, but only if the cart total is above…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

Every PHP developer knows this situation: a client calls and says "I want free shipping for VIP customers on weekends, but only if the cart total is above €100."



You open your code. You find the shipping module. You add an if. You deploy.

Three weeks later: "Actually, make it €80. And also for the 'Premium' group."



You open your code again.



This loop : client request -> find logic in code -> modify -> deploy, was costing me a lot of time. And it's not just shipping. I build custom ecommerce solutions: payment modules, synchronization systems, pricing calculators. Business rules are everywhere, and they change constantly.



The obvious solution I didn't want Symfony's ExpressionLanguage exists and it's impressive. But it pulls in dependencies, it can traverse objects and call methods (which is a security concern when rules are authored by users), and when something goes wrong, it doesn't tell you why. It's a black box.

I needed something smaller, stricter, and transparent.



So I built php-ruler



I started with the classic pipeline: Lexer → AST → Evaluator. Strict typing from the start — 1 = '1' is a type error, not true. No silent coercion.

Then I added features one real problem at a time.



Problem: when something fails, why?



-> I built an explain mode that returns the full evaluation tree: which sub-conditions passed, which failed, which were short-circuited, and why a variable was missing.



Problem: in production, the context is sometimes incomplete



-> I built a safe mode that doesn't throw on missing variables — it collects them all and lets you decide what to do.



Problem: customer.group.name is not user-friendly



-> I built an alias resolver. As a developer, I expose what I want:




$resolver = (new AliasResolver())
->add('customer.group', 'customer group')
->add('cart.total', 'cart amount');






Now a non-developer can write: customer group = 'VIP' AND cart amount > 100



And I control exactly what variables are available to them.



A real example

Here's the shipping rule that started it all:




$eval = new ExpressionEvaluator();

$context = [
'customer' => ['group' => 'VIP'],
'cart' => ['total' => 150.00],
'day' => 'saturday',
];
$rule = "customer.group = 'VIP' AND cart.total > 100 AND day IN ['saturday', 'sunday']";

$eval->evaluateBoolean($rule, $context); // true -> free shipping






This rule lives in the database. When the client wants to change it, they change it - no deployment, no code change.



Same pattern for payment modules (who can use this payment method?), synchronization systems (apply a margin to these products above this price?), or any eligibility check.



What it looks like when something goes wrong

The explain mode is what I'm most proud of:




$explainer = new ExpressionExplainer($eval);
$result = $explainer->explain(
"customer.group = 'VIP' AND cart.total > 100",
$context
);

$result->passed; // true | false | null
$result->failures(); // leaves that returned false
$result->missing(); // variables that were absent






Every node in the tree carries its sub-expression, its status, and the resolved values. No more guessing why a rule didn't fire.



Zero dependencies. PHP 8.1+.




composer require ols/php-ruler






There's also a local demo playground (no build step, no Composer):




php -S localhost:8000 -t demo






-> github.com/olivier-ls/php-ruler



I built this because I needed it, and I've been running it in production for my own ecommerce clients. If you maintain systems where business rules change often, it might save you some late-night deploys.



Happy to answer questions.

Intelligence Digest — kostenlos Täglich die wichtigsten Security-News · jederzeit abbestellbar
Community Rating & Social Proof
⭐ Leser-Wertung
–
Ø / 5.0
Noch keine Leser-Bewertungen
War diese Seite hilfreich?
0
Jetzt Bewertung abgeben
🟢 Niedrig (1-3.9) 🟡 Mittel (4.0-6.9) 🔴 Hoch (7.0-8.9) Kritisch (9.0-10.0)

Verwandte Story-Cluster & Quellen (Vektor-KI)

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten How I stopped hardcoding business rules in PHP - and built a rule engine to fix it

Thematisch verwandte Begriffe: stopped, hardcoding, business, rules · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Reacties worden geladen…
Trek om te vernieuwen
Nächster Beitrag