Weave Code
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

Math Laravel Package

php-standard-library/math

Strictly typed math utilities for PHP with predictable, consistent error handling. Part of the PHP Standard Library project, providing reliable mathematical functions and a stable developer experience for safer numeric operations.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require php-standard-library/math
    

    No configuration required—package is dependency-free.

  2. First Use Case: Replace loose arithmetic with strict, typed operations. Example:

    use Math\Division;
    
    // Instead of:
    $result = 10 / 0; // Silent NaN in PHP
    
    // Use:
    $result = Division::safeDivide(10, 0); // Returns null with no exception
    // Or throw on error:
    $result = Division::divide(10, 0); // Throws DivisionByZeroException
    
  3. Key Classes to Explore:

    • Math\Addition, Math\Subtraction: Strict addition/subtraction with overflow checks.
    • Math\Multiplication, Math\Division: Safe operations with zero-division handling.
    • Math\SquareRoot, Math\Logarithm: Scientific functions with domain validation.
    • Math\Range: Validate numeric ranges (e.g., Range::validate(10, 0, 100)).
  4. Where to Look First:

    • Package Source (minimal but clear).
    • Documentation (if updated; otherwise, inspect tests/ for usage examples).
    • tests/ directory for edge-case examples (e.g., Math\FactorialTest).

Implementation Patterns

Core Workflows

1. Strict Arithmetic in Business Logic

  • Pattern: Replace raw operators with typed methods in service layers.
  • Example:
    // Before (loose)
    $discount = $price * $percentage; // Silent type coercion
    
    // After (strict)
    $discount = Multiplication::multiply($price, $percentage);
    
  • Laravel Integration: Bind to the service container in AppServiceProvider:
    $this->app->bind(Multiplication::class, function () {
        return new Multiplication();
    });
    
    Use in controllers/services:
    use Illuminate\Support\Facades\App;
    
    $total = App::make(Multiplication::class)->multiply($subtotal, 1.08);
    

2. Input Validation

  • Pattern: Validate numeric inputs with Math\Range or custom rules.
  • Example:
    use Math\Range;
    use Illuminate\Validation\Rule;
    
    // Custom validation rule
    $validator->addRules([
        'age' => ['required', function ($attribute, $value, $fail) {
            if (!Range::validate($value, 0, 120)) {
                $fail('Age must be between 0 and 120.');
            }
        }],
    ]);
    
  • Laravel Form Requests:
    use Illuminate\Foundation\Http\FormRequest;
    use Math\Range;
    
    class StoreUserRequest extends FormRequest
    {
        public function rules()
        {
            return [
                'height' => ['required', 'numeric', function ($attribute, $value, $fail) {
                    if (!Range::validate($value, 0, 300)) {
                        $fail('Height must be between 0 and 300 cm.');
                    }
                }],
            ];
        }
    }
    

3. Computed Eloquent Attributes

  • Pattern: Use math functions in model accessors/mutators.
  • Example:
    use Math\Division;
    
    class Product extends Model
    {
        public function getDiscountedPriceAttribute()
        {
            return Division::safeDivide(
                $this->price,
                $this->discount_factor ?? 1
            );
        }
    }
    

4. Query Builder Offloading

  • Pattern: Avoid SQL math (risk of injection) by computing in PHP.
  • Example:
    use Math\Round;
    
    $roundedPrices = Product::query()
        ->get()
        ->map(fn ($product) => [
            'price' => Round::round($product->price, 2),
        ]);
    

5. CLI/Artisan Commands

  • Pattern: Process numeric data in batch jobs.
  • Example:
    use Math\Addition;
    use Illuminate\Console\Command;
    
    class NormalizePricesCommand extends Command
    {
        protected $signature = 'math:normalize-prices';
        protected $description = 'Adjust prices by a fixed percentage';
    
        public function handle()
        {
            $products = Product::all();
            foreach ($products as $product) {
                $newPrice = Addition::add(
                    $product->price,
                    Addition::multiply($product->price, 0.1) // 10% increase
                );
                $product->update(['price' => $newPrice]);
            }
        }
    }
    

6. API Response Transformation

  • Pattern: Ensure numeric precision in API responses.
  • Example:
    use Math\Round;
    use Illuminate\Http\Resources\Json\JsonResource;
    
    class ProductResource extends JsonResource
    {
        public function toArray($request)
        {
            return [
                'price' => Round::round($this->price, 2),
                'tax' => Round::round($this->price * 0.08, 2),
            ];
        }
    }
    

Integration Tips

  • Facade Wrapper: Create a Math facade for consistency with Laravel’s ecosystem:

    // app/Facades/Math.php
    namespace App\Facades;
    
    use Illuminate\Support\Facades\Facade;
    use Math\Addition;
    
    class Math extends Facade
    {
        protected static function getFacadeAccessor()
        {
            return Addition::class;
        }
    }
    

    Register in AppServiceProvider:

    Facade::alias('Math', \App\Facades\Math::class);
    

    Usage:

    $total = \Math::add(10, 20); // Alias for Addition::add()
    
  • Exception Handling: Centralize math exceptions in a global handler (e.g., app/Exceptions/Handler.php):

    public function render($request, Throwable $exception)
    {
        if ($exception instanceof \Math\MathException) {
            return response()->json([
                'error' => 'Invalid math operation',
                'details' => $exception->getMessage(),
            ], 400);
        }
        return parent::render($request, $exception);
    }
    
  • Testing: Use Pest/PHPUnit to test edge cases:

    // tests/Feature/MathOperationsTest.php
    use Math\Division;
    use Tests\TestCase;
    
    class MathOperationsTest extends TestCase
    {
        public function testDivisionByZeroThrowsException()
        {
            $this->expectException(\Math\DivisionByZeroException::class);
            Division::divide(10, 0);
        }
    
        public function testSafeDivisionReturnsNull()
        {
            $result = Division::safeDivide(10, 0);
            $this->assertNull($result);
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Strict Typing Breaks Legacy Code:

    • Issue: Passing null or non-numeric values to math functions throws InvalidInputException.
    • Fix: Use safe* variants or validate inputs:
      if (!is_numeric($input)) {
          throw new \InvalidArgumentException('Input must be numeric');
      }
      
  2. Overflow/Underflow Silently Fails:

    • Issue: Some functions (e.g., Math\Factorial) may not throw on overflow in PHP.
    • Fix: Set explicit bounds:
      $result = Math\Factorial::compute(min($input, 1000)); // Cap at 1000!
      
  3. Performance Overhead:

    • Issue: Strict typing adds ~10–20% runtime cost for simple operations.
    • Fix: Benchmark critical paths and use native PHP for trivial math:
      // Avoid for hot paths:
      $sum = Math\Addition::add($a, $b);
      // Prefer for hot paths:
      $sum = $a + $b;
      
  4. Floating-Point Precision:

    • Issue: Functions like Math\Division may still suffer from IEEE 754 quirks.
    • Fix: Use bcmath or gmp for arbitrary precision:
      $result = gmp_div_q($a, $b); // Alternative for high precision
      
  5. Laravel Caching Quirks:

    • Issue: Cached math results may stale if inputs are dynamic.
    • Fix: Use cache tags or versioned keys:
      $key = "math:discount:{$productId}:{$percentage}";
      $discount = Cache::remember($key, now()->addHours(1), function () use
      
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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony