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

No Floaters Laravel Package

roave/no-floaters

PHPStan plugin that bans floats: no float properties, parameters, return types, or assigning float values. Optional strict mode disallows any float-producing expression. Helps prevent rounding errors in domains like money, grading, or scientific calculations.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require --dev roave/no-floaters
    

    Note: This release (1.16.0) drops PHP 8.3 support entirely. Ensure your project uses PHP 8.1 or 8.2 (no PHP 8.3 compatibility).

  2. First Use Case Run the static analyzer on your codebase:

    vendor/bin/no-floaters
    

    This includes conditional return type handling (e.g., detecting floating-point expressions in ternary or conditional return types like function foo(): float { return $floatVar ? 1.0 : 2.0; }).

  3. Where to Look First

    • Check config/no-floaters.php for custom rules (if auto-generated).
    • Review tests/ for examples of flagged operations, including conditional return types.
    • Focus on:
      • Financial calculations (e.g., tax logic, payments).
      • Scientific computations (e.g., physics simulations).
      • Generic/conditional return type functions where floats may leak unintentionally.

Implementation Patterns

Workflows

  1. Integrate with CI/CD Add to composer.json under scripts:

    "scripts": {
        "test": [
            "@phpstan",
            "no-floaters"
        ]
    }
    

    Run via composer test in your pipeline. Note: Ensure your CI environment uses PHP 8.1–8.2 (no PHP 8.3).

  2. Custom Rules Extend rules in config/no-floaters.php:

    return [
        'rules' => [
            'Roave\NoFloaters\Rules\DivisionByFloat',
            'Roave\NoFloaters\Rules\ConditionalReturnType',
            'App\Custom\Rules\NoFloatMultiplication',
        ],
    ];
    

    The ConditionalReturnType rule detects floating-point expressions in conditional return types (e.g., ternary operators or ?: syntax).

  3. Excluding Files/Directories Use .no-floaters-exclude file or CLI args:

    vendor/bin/no-floaters --exclude=tests/unit/
    
  4. Fixing Violations

    • Replace floats with integers where possible (e.g., 1 / 3 instead of 1.0 / 3.0).
    • Use bcmul(), bcdiv() for arbitrary precision (Laravel’s bcmath helper):
      $result = bcdiv('1', '3', 10); // 10 decimal places
      
    • For conditional return types, refactor to avoid mixing float literals:
      // Before (flagged)
      function getDiscount(): float { return $isPremium ? 1.0 : 0.0; }
      
      // After
      function getDiscount(): float { return $isPremium ? 1 : 0; }
      
  5. Laravel-Specific Patterns

    • Database Interactions: Avoid DB::raw('SELECT * FROM users WHERE score > 1.0'). Use integers or CAST in SQL.
    • Validation: Use Integer or Numeric rules instead of Float:
      $request->validate(['price' => 'integer']); // or 'numeric'
      
    • Eloquent: Prefer integer columns for monetary values (use cents, e.g., 999 for $9.99).
    • Conditional Logic: Refactor conditional return types in Laravel services:
      // Before (flagged by ConditionalReturnType)
      public function calculateTax(): float { return $isVatApplicable ? 1.2 : 1.0; }
      
      // After
      public function calculateTax(): float { return $isVatApplicable ? 120 : 100; }
      

Gotchas and Tips

Pitfalls

  1. PHP Version Compatibility (BREAKING CHANGE)

    • No PHP 8.3 Support: This release drops PHP 8.3 compatibility entirely. Update composer.json:
      "require": {
          "php": ">=8.1.0,<8.3.0"
      }
      
    • Verify your CI/CD and local environments comply.
  2. False Positives

    • Conditional Return Types: The ConditionalReturnType rule may flag legitimate cases like:
      function getRatio(): float { return $isValid ? 1.0 / 3.0 : 0.0; }
      
      Solution: Exclude specific files or adjust rules:
      'exceptions' => [
          'App\Services\RatioCalculator', // Exclude class
      ],
      
    • Math Constants: M_PI or E may still trigger rules. Exclude them in config:
      'exceptions' => [
          'M_PI',
          'E',
      ],
      
  3. Performance Overhead

    • Static analysis adds ~5-10s to CI runs. Cache results with phpstan:
      vendor/bin/no-floaters --cache-results
      
  4. Precision Assumptions

    • Floating-Point Comparisons: Avoid == for floats. Use abs($a - $b) < 0.0001 or bccomp():
      if (bccomp($floatA, $floatB, 6) === 0) { ... }
      
  5. Legacy Code

    • Gradually refactor high-risk areas (e.g., payment logic). Use --fix mode (if available) to auto-correct simple cases.
    • Conditional Return Types: Prioritize refactoring functions with ternary operators or ?: syntax returning floats.

Debugging

  • Verbose Output: Run with -v to see file-by-file violations:
    vendor/bin/no-floaters -v
    
  • Rule-Specific Debugging: Isolate a rule, including the ConditionalReturnType:
    vendor/bin/no-floaters --rules=ConditionalReturnType
    
  • Conditional Logic: Use -vv for detailed analysis of conditional return types:
    vendor/bin/no-floaters -vv
    

Extension Points

  1. Custom Rules Extend Roave\NoFloaters\Rules\AbstractRule to create domain-specific checks (e.g., "no floats in tax calculations"). Example: Override ConditionalReturnType for custom logic:

    use Roave\NoFloaters\Rules\AbstractRule;
    
    class NoFloatInDiscounts extends AbstractRule
    {
        public function __invoke(Node $node): ?string
        {
            if ($node instanceof ConditionalReturnType && $node->getReturnType() === 'float') {
                return 'Floating-point discounts are not allowed.';
            }
            return null;
        }
    }
    
  2. Integration with PHPStan Combine with phpstan for deeper analysis:

    vendor/bin/phpstan analyse --level=max --memory-limit=2G
    

    Add to phpstan.neon:

    includes:
        - vendor/roave/no-floaters/phpstan/extension.neon
    
  3. IDE Support

    • Use phpstan/extension-installer to auto-load rules in PHPStorm:
      composer require --dev phpstan/extension-installer
      
    • Configure PHPStorm to run no-floaters on save via Settings > Tools > External Tools.
  4. Laravel Artisan Command Create a custom Artisan command to wrap no-floaters:

    // app/Console/Commands/CheckFloaters.php
    public function handle()
    {
        $this->call('vendor:publish', ['--provider' => 'Roave\NoFloaters\NoFloatersServiceProvider']);
        $this->info('Running NoFloaters (including ConditionalReturnType checks)...');
        $exitCode = Artisan::call('no-floaters');
        if ($exitCode !== 0) exit($exitCode);
    }
    
  5. Testing Conditional Logic Add tests for conditional return types in your project:

    // tests/Unit/NoFloatersTest.php
    public function testConditionalReturnTypeDetection()
    {
        $this->assertViolation(
            'ConditionalReturnType',
            'function foo(): float { return $bool ? 1.0 : 2.0; }'
        );
    }
    
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console