zofe/burp
zofe/burp is a Laravel package for creating and restoring database backups from the command line. It provides straightforward Artisan commands for dumping your database and recovering from a backup, making routine snapshots and simple recovery easier in Laravel projects.
Install
composer require zofe/burp
There is no Laravel service provider story here worth chasing — this is a standalone router with a Laravel-flavoured filter syntax, not a Laravel package. If you're inside a Laravel app, use the framework's own router instead; burp is aimed at plain PHP projects.
Where to look first
README.md — the examples are short, but they establish the two dispatch styles (URI segments vs. query string) and the filter syntax.src/ — the whole library is small enough to read in one sitting (~a few files). Confirm the actual class name/namespace (Burp\…) and the exact method names before copying any snippet from this assessment; the README and code have drifted in packages this size.composer.json — check the php constraint. An 18-star, 0-dependent package is almost certainly not tracking PHP 8.x compatibility.First use case
A front controller for a small site or legacy app where you want Laravel-4-era routing (named routes, before/after filters for auth and logging) without pulling in a framework. Drop an index.php at the web root, rewrite everything to it, and let burp pick the handler:
# .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
// index.php
require __DIR__ . '/vendor/autoload.php';
$router = new Burp\Router();
$router->get('/', fn() => 'home');
$router->get('/users/{id}', fn($id) => "user {$id}");
$router->run();
Decide up front which matching mode you're committing to. The query-string mode (index.php?route=users&id=42) is the escape hatch for hosts where you can't touch rewrite rules; the URI-segment mode is what you actually want if you control the server. Mixing them in one app is the fastest way to make routing behaviour unpredictable.
Front controller + routes.php split. Keep index.php to bootstrap, config, and one require 'routes.php'. Route files stay declarative and diffable; the bootstrap stays boring.
Filters are your middleware. This is the package's main selling point — the "Laravel filter system" means you can register a named filter once and attach it to a route or a group of routes:
$router->filter('auth', function () {
if (empty($_SESSION['user'])) {
header('Location: /login');
return false; // short-circuits the route
}
});
$router->get('/admin', ['before' => 'auth', fn() => render('admin')]);
Use this for: auth gates, request logging, CSRF checks on POST, maintenance-mode redirects, and setting up shared view data.
Wrap output, don't echo from closures. Return strings (or a small Response value object you define) from handlers and let the front controller print. It keeps handlers testable and lets an after filter post-process output — compression, debug-toolbar injection, cache headers.
Parameterised segments. Treat {id}-style placeholders as untrusted input. Cast and validate at the top of every handler ((int) $id, or a regex constraint if the router supports it) rather than trusting the route to have constrained anything.
Group by prefix. For admin/API sections, define a small helper that loops over a route array and applies a shared before filter plus a path prefix. burp is thin enough that a 15-line wrapper gives you the grouping you'd otherwise miss.
Container/DI integration. Since handlers are closures, inject dependencies by use at route-definition time — pull the PDO instance, mailer, etc. from a bootstrap-level container and close over them. Don't reach for globals inside handlers.
Compose with a standalone template engine. Blade standalone or Twig fits naturally: the handler gathers data, the template renders, the router returns the string. This combination is the sweet spot for the package — roughly Laravel-shaped without the framework.
composer.json, and be prepared to fork. Read the source before building anything that matters on it.REQUEST_URI/PATH_INFO. Deploying into a subdirectory (/app/) or behind a proxy that rewrites the path silently breaks matching. Test with your real vhost config, not php -S alone./users vs /users/ are usually different routes. Pick one canonical form, normalise in the front controller, and 301 the other.return false from a before filter is the short-circuit contract — confirm it in the source. If a filter returns something falsy-but-not-false, or the router ignores the return value, your auth gate silently doesn't gate. Write one test that asserts a filtered route does not execute its handler.auth before log vs. after changes what gets logged on a rejected request. Be explicit.each(), create_function, curly-brace string offsets, implode() argument order. A package this size from the Laravel 4 era will likely need a patch or two. Running it under PHP 8 with E_ALL in dev will surface these immediately.group() method, or add route caching. Resist forking until you've tried subclassing.$_SERVER['REQUEST_URI'], PATH_INFO, QUERY_STRING) — nine times out of ten the mismatch is there, not in your route definition.nikic/fast-route (with middlewares/*) or bramus/router give you the same shape with maintenance and a community; Slim if you want the full PSR-7 stack. burp is only worth it when the scope is genuinely a handful of routes and you want zero ceremony.How can I help you explore Laravel packages today?