sebastian/exporter
Exports PHP variables into readable, stable string representations for debugging and test output. Handles scalars, arrays, objects, resources, binary strings, and recursive structures with reference tracking for clear visualization.
Installation:
Update to the latest version (now 8.1.0) in composer.json:
composer require --dev sebastian/exporter:^8.1
For production debugging (rare), omit --dev.
First Use Case:
Replace var_dump() or dd() in a Laravel controller or Artisan command:
use SebastianBergmann\Exporter\Exporter;
$exporter = new Exporter();
$data = User::with('posts')->find(1);
echo $exporter->export($data); // Clean, recursive-safe output with improved `SplObjectStorage` handling
Where to Look First:
SplObjectStorage and binary string improvements.Exporter class: Core methods now handle iterator positions better (see #57).SplObjectStorage and binary string readability.SplObjectStorage// Circular reference-safe dump (now preserves iterator position)
$exporter = new Exporter();
$user = User::with('roles')->find(1);
$user->customData = new SplObjectStorage(); // Now won't reset iterator
echo $exporter->export($user);
// Improved readability for mostly-printable binary strings
$binaryData = file_get_contents('/path/to/file');
echo $exporter->export($binaryData); // More human-readable output
$response = Http::get('https://api.example.com/data');
$data = $response->json();
echo $exporter->export($data, 100); // Limit string length (unchanged)
use SebastianBergmann\Exporter\Exporter;
class DebugCommand extends Command {
protected $signature = 'debug:model {model}';
public function handle() {
$model = app($this->argument('model'))::first();
$this->line((new Exporter())->export($model));
}
}
public function handle($request, Closure $next) {
if ($request->header('X-Debug')) {
$response = $next($request);
$response->headers->set('X-Debug-Data', (new Exporter())->export($request->all()));
return $response;
}
return $next($request);
}
Debugbar::extend() to add an "Exporter" tab (unchanged).dd() in AppServiceProvider (unchanged).shortenedExport() for production logs (unchanged).SplObjectStorage in Collections:
If using SplObjectStorage in custom collections, ensure iterator positions are preserved:
$collection = new CustomCollection();
$collection->storage = new SplObjectStorage(); // Iterator position now preserved
SplObjectStorage Iterator Reset:
Binary Strings:
Performance with Large Arrays:
shortenedExport() or limit depth:
$exporter->export($array, 10); // Max depth
Private Properties:
toArray() still drops private properties. Use reflection if needed.PHP 8.5+ Warnings:
^8.1 to avoid warnings:
composer require sebastian/exporter:^8.1
$exporter = new Exporter(100, 5); // Max string length, depth
SplObjectStorage:
$storage = new SplObjectStorage();
$storage->attach(new StdClass());
echo $exporter->export($storage); // Iterator position preserved
shortenedExport() in production logs (unchanged).Custom Exporters:
Extend Exporter to handle Laravel-specific types (e.g., Carbon, Collection):
class LaravelExporter extends Exporter {
protected function exportCarbon(CarbonInterface $carbon) {
return "Carbon: {$carbon->toIso8601String()}";
}
}
Formatters:
Override format() for custom output (e.g., JSON):
$exporter = new Exporter();
$data = $exporter->toArray($object);
return response()->json($data);
Hooks for SplObjectStorage:
Customize SplObjectStorage export behavior:
$exporter->exportVariable($variable) {
if ($variable instanceof SplObjectStorage) {
return "SplObjectStorage (size: " . $variable->count() . ")";
}
return parent::exportVariable($variable);
}
with() to avoid N+1 queries before exporting (unchanged).app/Providers/DebugbarServiceProvider (unchanged).SplObjectStorage in Eloquent:
If using SplObjectStorage in accessors/mutators, iterator positions are now preserved:
public function getCustomDataAttribute() {
$storage = new SplObjectStorage();
// ... populate storage ...
return $storage; // Iterator position preserved on export
}
How can I help you explore Laravel packages today?