Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Formulate Laravel Package

rezzza/formulate

rezzza/formulate is a Laravel form-building package that lets you declare fields, validation, and layout in PHP, then render clean HTML forms and bind data to models. It helps keep form markup and rules centralized and reusable across your app.

Deep Wiki
Context7

Getting Started

composer require rezzza/formulate

Before writing any code, check three things, in this order:

  1. composer.json for PHP constraints. Last release was May 2016, so expect php: ~5.5|~5.6|~7.0 style constraints and no return types or scalar hints. On PHP 8 you will almost certainly need --ignore-platform-reqs to install, and you should run the package's own test suite immediately to see what breaks.
  2. src/, not the README. This is a 12-star, single-purpose package from 2016; the source is the documentation. It is small enough to read end-to-end in one sitting, and you need to know the exact class names before you build around them.
  3. tests/ for the intended usage. The test suite is usually where abandoned packages hide their real, working examples.

The first use case to reach for is a formula that appears in more than one place: a pricing calculation, an interest/amortization schedule, a scoring rule, or a VAT breakdown. Instead of duplicating the string "price * quantity * (1 + tax)" in a controller, a template and a report query, you model it once, evaluate it with inputs, and optionally render it for display.

Illustrative shape (verify exact class names against src/):

use Rezzza\Formulate\Formula;

$formula = new Formula('(price * quantity) * (1 + tax)');

$total = $formula->evaluate([
    'price'    => 10.0,
    'quantity' => 3,
    'tax'      => 0.20,
]);

// 36.0

If the package exposes a builder rather than a string parser, the same idea applies — construct the formula object once at the edge of your application, pass variables in at evaluation time.

Implementation Patterns

Wrap the package behind your own service. The package is unmaintained; you want a seam you can replace with symfony/expression-language, brick/math, or a hand-rolled parser later without touching call sites.

final class FormulaEvaluator
{
    /** @var array<string, object> parsed formulas, keyed by formula id */
    private array $cache = [];

    public function evaluate(string $id, string $expression, array $variables): float
    {
        $formula = $this->cache[$id] ??= $this->parse($expression);

        return (float) $formula->evaluate($variables);
    }
}

Parse once, evaluate many. Whatever the entry point is (Formula, a parser, a builder), treat construction as the expensive step. If a formula is evaluated in a loop — per line item, per user, per month — build it outside the loop. This is the single biggest performance win with a 2016-era string parser.

Define formulas as data, not code. Keep expressions in config, a database column, or a dedicated FormulaRegistry class keyed by name. This lets product/finance change a coefficient without a deploy, and it makes formulas greppable and reviewable. Never accept a formula string from user input and evaluate it without a whitelist of allowed variables and functions — you are one step away from arbitrary execution.

Validate the variable contract explicitly. The package will not tell you nicely which variables are missing. Assert the required keys before calling evaluate() and throw your own domain exception with the formula name and missing keys — debugging Undefined index: tax three layers deep in a parser is miserable.

$missing = array_diff($required, array_keys($variables));
if ($missing) {
    throw new FormulaInputException(sprintf(
        'Formula "%s" missing: %s', $name, implode(', ', $missing)
    ));
}

Separate evaluation from rendering. Use the formula for numbers, but if the package also produces a display representation (LaTeX/HTML/markdown), route that through a Twig extension or view helper rather than calling it from a controller. Pre-render and cache the display string when formulas are shown repeatedly.

Test with data providers, not one-offs. Formula bugs are edge-case bugs: zero, negative, boundary coefficients, division by zero, rounding at half-cent. A table-driven PHPUnit test with a dozen input/expected rows per formula is the cheapest insurance you'll buy.

/**
 * @dataProvider totals
 */
public function testTotal(string $expr, array $vars, float $expected): void
{
    self::assertSame($expected, (new Formula($expr))->evaluate($vars));
}

In Symfony, register it as a service. Bind the evaluator and a formula registry as services, inject the registry into consumers, and tag a Twig extension for display. Avoid new Formula(...) sprinkled through controllers — it defeats the seam you built.

Gotchas and Tips

  • It is abandoned. Twelve stars, one release in 2016, no PHP 8 support. Pin the version, commit the lockfile, and budget for a fork or replacement. Check composer outdated and vendor-patch rather than waiting for upstream.
  • Operator precedence is the top source of wrong answers. Do not trust implicit precedence for mixed + - * /; parenthesize aggressively. Write ((a + b) * c) even when it "shouldn't" be needed. If the parser handles unary minus or exponentiation, test -2^2 and 2^3^2 explicitly and document what you get.
  • Implicit multiplication is a trap. 2(3+4) may or may not parse depending on the tokenizer; prefer explicit * everywhere.
  • Locale and decimal separators. Strings like "1,5" will not do what a French user expects. Normalize all inputs to float on the PHP side and format only at the presentation boundary.
  • Floating point, always. 0.1 + 0.2 is not 0.3. For money, evaluate in cents or wrap with bcmath/brick/math, and round once — at the very end — with an explicit policy (round($v, 2, PHP_ROUND_HALF_UP)).
  • Division by zero and guard clauses. The package likely lets PHP raise a warning/fatal or return INF. Check denominators yourself before evaluating; a Warning: Division by zero buried in a report job is hard to trace back to the formula.
  • Explicit exception handling. Find the package's exception class (if any) and catch it at the boundary, logging the formula name, the expression and the inputs — not just the message. That log line is what makes production debugging possible.
  • Extension points before forking. If you need a custom function or operator, look for an operator/function registry or interface in src/ first. If none exists, that's a strong signal to replace the package rather than patch it.
  • Debug the parse tree, not just the result. If the package exposes an AST or a __toString(), dump it when a formula returns a surprising number. If it doesn't, temporarily wrap the tokenizer/parser in a small script — a wrong tree explains a wrong answer far faster than staring at the expression.
  • Escape on output. If you render formulas into HTML/LaTeX, escape variables before interpolation. A user-supplied variable name flowing raw into a template is the same class of bug as an unescaped {{ }} — just less obvious.
  • Vendor the tests, not just the code. When you fork for PHP 8 compatibility, you'll want the original test suite to prove the fix didn't change behavior; port the @dataProvider-style tests to modern PHPUnit attributes as you go.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib