Home » Php » Laravel – Get variable from a DB Transaction Closure

Laravel – Get variable from a DB Transaction Closure

Posted by: admin November 29, 2017 Leave a comment

Questions:

I am working with a Laravel 5 LAMP stack, and I am trying to process a CSV import with a database transaction. Code looks like this:

// Should contain any messages to pass back to the user
$results = [];

// Contains the total records inserted
$total = 0;

DB::transaction(function() use($csv_file, $results, $total) {

    // Some Code ...

    $total++;
    $results[] = 'Row 10 has some weird data...';
});

return view('plan.import')
    ->with('results', $results)
    ->with('total', $total);

At the end of that, my records are imported, but my $total and $results are still empty, since they are outside the scope of the closure. I know they are being altered inside the function, because I’ve stepped through it, and seen them change. I just can’t figure how to get them out of that transaction and return them to the user. Can anyone please help with this?

Answers:

You may replace the following line:

DB::transaction(function() use($csv_file, $results, $total)

with this:

DB::transaction(function() use($csv_file, &$results, &$total)

So the changes made inside the function will reflect in the variables because & creates a reference of the variable (Passes the variable reference) instead of passing them by value. Check Passing by Reference Manual.

Alternatively, you can return the variables from inside the closure like:

$array = DB::transaction(function() use($csv_file, $results, $total) {

    // Some Code ...

    $total++;
    $results[] = 'Row 10 has some weird data...';
    return compact('total', 'results');
});

Then use it like:

return view('plan.import')
->with('results', $array['results'])
->with('total', $array['total']);