nzo/grabber-bundle
nzo/grabber-bundle is a Laravel package that adds grabber functionality to your application, offering a framework-friendly way to pull in and work with external content. Install it via Composer and wire it into your project configuration to start using its grabbing features with minimal setup.
1. Confirm you're actually on v3
composer show vendor/package
v3.0.0 is a major bump. Two changes drive it: a configuration update and Symfony 4 compatibility. The Symfony 4 line drops support for Symfony 2/3 components and, by extension, the PHP versions those required. Before anything else, check your composer.json PHP constraint — if you're still on PHP 7.0, you cannot take this release.
2. Republish the config — do not assume your old file still works
This is the single most important first step. "Update configuration" in a major release usually means renamed keys, changed defaults, or a flattened/nested structure. Your existing config/<package>.php was published from v2 and will keep loading silently, with new keys falling back to internal defaults you never chose.
# Inspect the diff before overwriting
php artisan vendor:publish --provider="Vendor\Package\ServiceProvider" --tag=config --force
# Then reconcile by hand against your git diff
git diff config/
Treat the published file as the source of truth for the new release, and port your environment-specific values into it rather than the reverse.
3. First use case
Resolve the package from the container rather than instantiating it, so the config bindings and any Symfony-component wiring are applied:
use Vendor\Package\Client;
public function __construct(private Client $client) {}
public function __invoke()
{
return $this->client->handle(/* ... */);
}
If it resolves and returns without error, your config keys are at least syntactically right. If it throws a BindingResolutionException or an "undefined config key" warning, go back to step 2.
Where to look first, in order: the published config file → the package's service provider (what it binds and with which config keys) → the upgrade notes for v3 → your composer.lock diff.
Config-driven construction, environment-scoped
Keep all package behavior in the published config and drive environment differences through .env, not through branching in application code. The v3 config update is a good moment to audit whether your config has hardcoded values that should be env vars:
// config/package.php
return [
'driver' => env('PACKAGE_DRIVER', 'default'),
'timeout' => env('PACKAGE_TIMEOUT', 30),
];
Because v3 changed the shape of this file, grep your codebase for direct config('package.…') reads before deploying — those are the call sites that break when a key moves.
Wrap the package behind your own binding
For anything beyond a single call site, bind the package's client to an interface in your own service provider. This is what makes the next major bump cheap:
// app/Providers/AppServiceProvider.php
$this->app->bind(ThingGateway::class, fn ($app) => $app->make(Vendor\Package\Client::class));
Consumers depend on ThingGateway. When v4 renames the client, you change one line.
Test against the container, not the class
public function test_it_handles_payloads(): void
{
$this->app['config']->set('package.driver', 'fake');
$this->app->instance(Vendor\Package\Client::class, $mock = Mockery::mock(Vendor\Package\Client::class));
$mock->shouldReceive('handle')->once()->andReturn(/* ... */);
$this->postJson('/endpoint', [/* ... */])->assertOk();
}
Since v3's config keys changed, tests that set config directly (rather than relying on config/package.php) are the ones that survive the upgrade — they document which keys you actually depend on.
Symfony-4-dependent features
If your reason for upgrading is Symfony 4 support, the practical effect is that the package can now coexist with dependencies pinned to ^4.0 — HTTP clients, console components, mailers. Check that your other packages aren't still forcing symfony/*: ^3.4; Composer will refuse to resolve v3 alongside them, and that's the most common upgrade blocker. Once resolved, you can share Symfony 4 services (e.g. a Psr\Log\LoggerInterface binding) with the package rather than duplicating them.
Stale config cache is the #1 cause of "the config update did nothing." In production, php artisan config:cache bakes config into a single file. Deploying v3 without clearing it leaves you running v2 config keys against v3 code — usually an undefined-index or silently-wrong default. Make php artisan config:clear (or a full optimize:clearn + optimize) part of the deploy script, and verify with php artisan tinker → config('package') that you see the new shape.
Do not skip the config diff. The release note says "update configuration" without specifying whether keys were renamed, removed, or merely reordered. If a key was removed and you're still reading it, config() returns null and your app keeps running with a broken default instead of erroring. Grep both the config file and your source for each old key name.
Silent defaults. Laravel's config merge means a missing key quietly falls back. If v3 renamed package.api_key to package.credentials.key, your app will not throw — it will just send unauthenticated requests. Test one real call against a sandbox environment after upgrading, not just a green test suite.
Composer resolution failures. symfony/*: ^3.4 anywhere in your tree blocks v3. Use composer why-not vendor/package 3.0.0 to find the actual blocker rather than guessing. Also check PHP: Symfony 4 requires PHP 7.1.3+, and while v3 may support higher, transitive constraints can demand more.
PHP version pinning in CI. If your .github/workflows or Dockerfile pins 7.0/7.1, the upgrade will pass locally and fail in CI. Update the matrix in the same PR as the dependency bump.
Extension points to keep your own changes out of vendor/: register additional container bindings in AppServiceProvider, hook package events/listeners rather than editing the provider, and use config overrides from a per-environment config file if the package supports it. Anything you patch inside vendor/ disappears on the next composer install.
Debugging order that actually works: (1) config('package') in tinker — is the shape what v3 expects? (2) composer show vendor/package — did I really get 3.x? (3) php artisan config:clear — am I looking at cached values? (4) Is the exception coming from the package or from a Symfony 4 service I've wired into it?
Watch for deprecations introduced in 3.0. Majors often ship new deprecation notices announcing the v4 removal story. Enable deprecation logging (LOG_LEVEL=debug or a E_USER_DEPRECATED handler) for a week post-deploy; it's far cheaper to fix now than at the next major.
How can I help you explore Laravel packages today?