| Install | |
|---|---|
composer require devportolio/laravel-dump-viewer |
|
| Latest Version: | v1.1.0 |
| PHP: | ^8.2 |
A beautiful, modern, and powerful in-browser debugging tool for Laravel applications. Inspired by Spatie Ray, but designed as a web-based viewer with persistent storage, real-time updates, and an intuitive interface.
php artisan tinker->label() and ->stop()composer require devportolio/laravel-dump-viewer --dev
php artisan vendor:publish --tag=dump-viewer-config
php artisan vendor:publish --tag=dump-viewer-assets
// Simple dump
dumpx($user);
// Dump with label
dumpx($user)->label('User Data');
// Dump multiple values
dumpx($user, $post, $comments);
// Multiple values with label
dumpx($a, $b, $c)->label('Debug Values');
// Label and stop
dumpx($data)->label('Final State')->stop();
After calling dumpx(), open your browser to:
http://your-app.test/dump-viewer
Route::get('/test', function () {
$user = User::first();
// Dump the user
dumpx($user)->label('First User');
// Continue execution
return view('test');
});
php artisan tinker
>>> $user = User::first()
>>> dumpx($user)->label('User from Tinker')
>>> dumpx(User::count())->label('Total Users')
Then open the viewer in your browser to see the dumps!
class MyCommand extends Command
{
public function handle()
{
$data = $this->fetchData();
dumpx($data)->label('Command Data');
$this->info('Data dumped to viewer!');
}
}
$query = DB::table('users')
->where('active', true)
->toSql();
dumpx($query)->label('User Query');
// Automatically formats with syntax highlighting!
$user = User::with('posts', 'comments')->first();
dumpx($user)->label('User with Relations');
// Beautifully renders model attributes and relationships
$users = User::take(100)->get();
dumpx($users)->label('Users Collection');
// Smart rendering with expand/collapse
After publishing the config file, you can customize:
// config/dump-viewer.php
return [
// Enable/disable the dump viewer
'enabled' => env('DUMPX_ENABLED', true),
// Route to access the viewer
'route' => env('DUMPX_ROUTE', 'dump-viewer'),
// Maximum dumps to store
'storage_limit' => env('DUMPX_STORAGE_LIMIT', 500),
// Storage driver (file, redis, database, etc.)
'storage_driver' => env('DUMPX_STORAGE_DRIVER', 'file'),
// Middleware for the viewer route
'middleware' => ['web'],
];
Add to your .env file:
# Enable/disable dump viewer
DUMPX_ENABLED=true
# Custom route
DUMPX_ROUTE=dump-viewer
# Storage settings
DUMPX_STORAGE_DRIVER=file
DUMPX_STORAGE_LIMIT=500
// Organize related dumps
dumpx($query)->label('DB Query');
dumpx($result)->label('Query Result');
dumpx($processed)->label('Processed Data');
// Filter by label in the viewer
// All values get the same label
dumpx($var1, $var2, $var3)->label('Test Variables');
// Use ->stop() to dump and halt execution
dumpx($criticalData)->label('Critical Error')->stop();
// Or chain it
dumpx($data)->label('Before Error')->stop();
// Automatically truncates large collections
$users = User::all(); // 10,000 users
dumpx($users)->label('All Users');
// Shows warning and first 100 items
// Better approach:
dumpx(User::take(50)->get())->label('Sample Users');
public function store(Request $request)
{
dumpx($request->all())->label('Request Data');
$validated = $request->validate([...]);
dumpx($validated)->label('Validated Data');
$user = User::create($validated);
dumpx($user)->label('Created User');
return response()->json($user);
}
DB::listen(function ($query) {
dumpx($query->sql)->label('Query: ' . $query->time . 'ms');
});
Event::listen('*', function ($event, $payload) {
dumpx([
'event' => $event,
'payload' => $payload
])->label('Event: ' . $event);
});
class ProcessPodcast implements ShouldQueue
{
public function handle()
{
dumpx($this->podcast)->label('Processing Podcast');
// Process...
dumpx($result)->label('Process Complete');
}
}
The dump viewer is designed for development only:
// Disable in production
'enabled' => env('DUMPX_ENABLED', !app()->isProduction()),
// Or in .env
DUMPX_ENABLED=false
Add authentication middleware:
// config/dump-viewer.php
'middleware' => ['web', 'auth', 'admin'],
Use custom middleware:
class DumpViewerAccess
{
public function handle($request, Closure $next)
{
if (!app()->environment('local')) {
abort(404);
}
return $next($request);
}
}
// config/dump-viewer.php
'middleware' => ['web', DumpViewerAccess::class],
// Good: Organized and filterable
dumpx($query)->label('DB: User Query');
dumpx($result)->label('DB: Query Result');
dumpx($user)->label('User: Loaded');
dumpx($posts)->label('User: Posts');
// Bad: Hard to find and organize
dumpx($query);
dumpx($result);
// In your bootstrap or test setup
if (app()->environment('testing')) {
app('dumpx')->clear();
}
// Keep viewer open in browser
// Run commands in Tinker
// Refresh browser to see dumps
// Dump for immediate visibility
dumpx($data)->label('Debug Point');
// Log for permanent record
Log::debug('Debug point', ['data' => $data]);
| Feature | dumpx | Ray | Laravel Debugbar | dump/dd |
|---|---|---|---|---|
| Web Interface | ✅ Yes | ❌ Desktop App | ✅ Yes | ❌ No |
| Persistent Storage | ✅ Yes | ✅ Yes | ❌ Per Request | ❌ No |
| Tinker Support | ✅ Yes | ✅ Yes | ❌ No | ✅ Yes |
| Real-time Updates | ✅ Yes | ✅ Yes | ❌ No | ❌ No |
| Labeling | ✅ Yes | ✅ Yes | ❌ No | ❌ No |
| Cost | 🆓 Free | 💰 Paid | 🆓 Free | 🆓 Free |
| Setup | ⚡ Easy | 📱 Desktop | ⚡ Easy | ✅ Built-in |
1. Check if enabled:
php artisan tinker
>>> config('dump-viewer.enabled')
2. Check storage driver:
>>> config('dump-viewer.storage_driver')
// Should be 'file' for Tinker
3. Clear cache:
php artisan cache:clear
php artisan config:clear
4. Check file permissions:
chmod -R 775 storage/framework/cache
1. Ensure file driver:
DUMPX_STORAGE_DRIVER=file
2. Test cache:
>>> Cache::store('file')->put('test', 'works', 60)
>>> Cache::store('file')->get('test')
3. Manually check dumps:
>>> app('dumpx')->all()
1. Check route name:
>>> config('dump-viewer.route')
2. Clear route cache:
php artisan route:clear
3. List routes:
php artisan route:list | grep dump
Contributions are welcome! Please feel free to submit a Pull Request.
The MIT License (MIT). Please see License File for more information.
Made with ❤️ for the Laravel community