rahulalam31/laravel-abuse-ip
Laravel Abuse IP helps protect Laravel applications from abusive clients by tracking and blocking IP addresses. It offers middleware, database-backed blocklists, and Artisan commands for managing blocked IPs with minimal setup.
This release is primarily a hardening/cleanup pass with one genuinely new capability: a configurable switch for ip2long() conversion. Start there.
composer update <vendor>/<package> -W, then composer dump-autoload -o and boot the app. If you were importing concrete classes directly (rather than resolving through the container or a facade), grep your codebase for the old namespace before deploying.'use_ip2long' => env('IP_USE_IP2LONG', true).If you are evaluating rather than upgrading: the package is only worth adopting if you actually need integer IP columns for range queries or indexing. If you store IPs as VARCHAR(45) and never range-scan, the toggle is the only feature here you'd use.
Keep the toggle in config, not in code. The whole point of the 1.4 feature is environment-driven behavior. Set it in config/*.php via env(), and let per-environment .env files differ. Avoid if (config(...)) branches scattered through your domain code — wrap the conversion behind a single service or cast so the rest of the app never knows which mode is active.
Isolate conversion behind one boundary. The cleanest integration is a custom Eloquent cast or a small IpValue value object:
ip2long() when enabled, raw string when disabled.long2ip() when enabled and the stored value is an int, raw string otherwise.Match the column type to the mode. ip2long() on 64-bit PHP returns an int that can exceed PHP_INT_MAX only in the negative-wrap sense — the canonical fix is sprintf('%u', ip2long($ip)). That value does not fit a signed INT. Use unsignedBigInteger (or unsignedInteger if you accept IPv4-only) so both modes coexist; a VARCHAR column holding "2130706433" is a bug waiting to happen.
Plan for mixed-mode data. During a rollout you will have string rows and integer rows in the same table. Either:
format column) and branch the cast on it.Do not let the toggle flip silently against a populated table.
Use it in middleware for coarse analytics. Resolving and converting the IP once in middleware, then attaching it to the request or a DTO, avoids repeated conversion in logs, rate limiters, and audit trails.
Test both modes explicitly. In Pest/PHPUnit, override the config in setUp and assert round-trip equality (long2ip(ip2long($ip)) === $ip) for IPv4, plus the no-conversion path. Add one IPv6 fixture to prove the toggle-off path works and the toggle-on path is a documented gap rather than a crash.
Dependency-inject, don't static-call. Post-restructure, the package's internals are more likely to change than its container bindings. Type-hint the interface the service provider registers; that is the extension point that survived the refactor.
ip2long() returns false, not 0, on malformed input. false casts to 0, which is a valid-looking integer. Check with === false before persisting, or you will silently write 0.0.0.0.ip2long('255.255.255.255') yields -1. Always pass through sprintf('%u', ...) before storage, and be aware existing rows written without that guard are now corrupt under long2ip().ip2long(). The toggle does not fix this — it only lets you avoid the failure. If your traffic is IPv6-capable, either keep the toggle off or pair the package with inet_pton()-based handling.env() inside a published config is resolved at config-cache time. After changing the toggle in .env, run php artisan config:clear (and re-cache in deploy). A stale bootstrap/cache/config.php is the single most likely cause of "the feature doesn't work."Class not found at boot, or container resolution errors only on code paths your tests don't hit. Pin the exact version, deploy to staging, and check composer why-not before rolling forward."2130706433" in your UI; reading string rows as integers yields 0.tinker, config('...'), ip2long('203.0.113.7'), and sprintf('%u', ip2long('203.0.113.7')) side by side will immediately tell you which mode the app is in and whether your column type is adequate.src/ moved in 1.4 — treat it as private API.How can I help you explore Laravel packages today?