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

Psalm Insane Comparison Laravel Package

orklah/psalm-insane-comparison

Psalm plugin that flags “insane” string-to-number loose comparisons that change behavior in PHP 8 (RFC: Saner string to number comparisons). Helps you find risky == checks like non-empty string vs 0 before upgrading, and suggests safer typing/casts.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Plugin

    composer require --dev orklah/psalm-insane-comparison
    vendor/bin/psalm-plugin enable orklah/psalm-insane-comparison
    
  2. Run Psalm

    vendor/bin/psalm
    
    • The plugin will now flag comparisons between non-empty strings and 0 (or other numeric literals) that behave differently in PHP 7 vs. PHP 8.
  3. First Use Case: Pre-Migration Audit

    • Run Psalm on your codebase to identify all "insane comparisons" before upgrading to PHP 8.
    • Focus on legacy codebases or projects where PHP 7 behavior was relied upon.

Implementation Patterns

Workflow Integration

  1. CI/CD Pipeline

    • Add vendor/bin/psalm to your CI pipeline (e.g., GitHub Actions) to catch issues early.
    • Example GitHub Actions step:
      - name: Run Psalm Insane Comparison
        run: vendor/bin/psalm --no-cache
      
  2. Incremental Fixing

    • Use Psalm’s --report=json to generate a report and prioritize fixes:
      vendor/bin/psalm --report=json > psalm-report.json
      
    • Parse the JSON to identify files with the most issues and tackle them systematically.
  3. Team Collaboration

    • Share Psalm reports with teammates to align on fixes.
    • Use @var annotations (e.g., positive-int, numeric-string) to suppress false positives or clarify intent.
  4. Legacy Code Handling

    • For large codebases, disable the plugin for specific files/directories in psalm.xml:
      <file-list>
          <directory name="vendor" />
          <directory name="legacy" exclude="true" />
      </file-list>
      

Common Fix Patterns

Issue Type Recommended Fix Example
String vs. 0 Use strict equality (===) if ($str === $num)
String vs. numeric literal Cast to same type if ((int)$str == $num)
Dynamic numeric values Use @var annotations /** @var positive-int $value */
Numeric strings Use @var numeric-string /** @var numeric-string $input */

Gotchas and Tips

Pitfalls

  1. False Positives

    • The plugin may flag comparisons where the string could be numeric (e.g., "123").
    • Fix: Use @var numeric-string to suppress warnings for known numeric strings:
      /** @var numeric-string */
      $input = "123";
      if ($input == 0) { // No warning
      }
      
  2. Performance Overhead

    • Running Psalm with this plugin adds slight overhead. For large codebases, cache results:
      vendor/bin/psalm --cache-dir=~/.psalm-cache
      
  3. Edge Cases in Logic

    • The plugin doesn’t distinguish between intentional and accidental comparisons.
    • Tip: Review flagged comparisons manually if the logic is complex (e.g., if ($userInput == 0) where $userInput might be "0" or 0).
  4. PHP 8+ Codebases

    • If already on PHP 8, the plugin may still catch unintended behavior (e.g., "0" == 0 is true, but "abc" == 0 is false).
    • Tip: Use this to audit for subtle bugs introduced by the RFC.

Debugging Tips

  1. Suppress Specific Warnings Disable the plugin for specific files in psalm.xml:

    <plugin-classes>
        <plugin-class>Orklah\PsalmInsaneComparison\Plugin</plugin-class>
        <exclude-files>
            <directory>tests/</directory>
        </exclude-files>
    </plugin-classes>
    
  2. Understand the Underlying Logic

    • The plugin triggers for comparisons where:
      • Left operand: Non-empty string (or mixed type that could be a string).
      • Right operand: 0 or other numeric literal.
    • Example of a non-trigger:
      if ("0" == 0) { // No warning (both operands are strings/numbers)
      }
      
  3. Leverage Psalm’s --init Generate a psalm.xml config file to customize behavior:

    vendor/bin/psalm --init
    
    • Adjust level (e.g., level=1 for basic checks) or add custom types.
  4. Extension Points

    • The plugin is open-source. Contribute fixes for:
      • False negatives (missed comparisons).
      • Support for additional edge cases (e.g., null comparisons).
    • Check the GitHub Issues for open tasks.

Pro Tips

  1. Pair with Other Psalm Plugins Combine with psalm/plugin for stricter type checking:

    composer require --dev vimeo/psalm
    vendor/bin/psalm-plugin enable vimeo/psalm
    
  2. Automate Fixes with IDE Use PHPStorm’s "Quick Fix" (Alt+Enter) to apply common fixes (e.g., adding @var annotations) when Psalm flags an issue.

  3. Document Intentional Cases Add PHPDoc comments to clarify why a comparison is intentional:

    // Intentionally compare string "0" with 0 (PHP 7/8 behavior is desired).
    if ($flag == 0) { ... }
    
  4. Monitor Progress Track fixes over time by comparing Psalm reports:

    vendor/bin/psalm --report=json > before.json
    # After fixes...
    vendor/bin/psalm --report=json > after.json
    
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.
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime
canaltp/sam-ecore-application-manager-bundle
canaltp/sam-ecore-security-manager-bundle