Функция defer
Функция defer предоставляет удобный способ отложить выполнение кода до момента после отправки HTTP-ответа клиенту или после завершения работы консольной команды. Это полезно для выполнения ресурсоёмких операций, которые не должны задерживать ответ пользователю, таких как отправка уведомлений, обработка изображений или запись логов. Функция принимает один параметр - замыкание (callback), содержащее код, который должен быть выполнен с задержкой.
Синтаксис
<?php
defer($callback);
?>
Пример
Давайте выполним отправку уведомления после того, как пользователь успешно зарегистрирован:
<?php
use AppModelsUser;
class UserController extends Controller
{
public function store(Request $request)
{
$user = User::create([
'name' => $request->name,
'email' => $request->email,
]);
$message = "User registered: " . $user->email;
defer(function () use ($message) {
info($message);
});
return response()->json(['status' => 'success']);
}
}
?>
Результат выполнения кода:
{"status":"success"}
Сообщение будет записано в лог после отправки ответа:
"User registered: user@example.com"
Пример
Используем defer для выполнения нескольких операций в консольной команде:
<?php
namespace AppConsoleCommands;
use AppModelsUser;
class ProcessDataCommand extends Command
{
public function handle()
{
$users = User::where('active', true)->get();
foreach ($users as $user) {
$id = $user->id;
defer(function () use ($id) {
sleep(1);
info("Processed user: " . $id);
});
}
return "Users will be processed";
}
}
?>
Результат выполнения кода:
"Users will be processed"
После завершения команды все отложенные операции выполнятся:
"Processed user: 1"
"Processed user: 2"
"Processed user: 3"
Пример
Отложим выполнение в контроллере с использованием данных из базы данных:
<?php
use AppModelsArticle;
use AppServicesAnalyticsService;
class ArticleController extends Controller
{
public function index()
{
$articles = Article::where('status', 'published')
->orderBy('created_at', 'desc')
->get();
$count = $articles->count();
defer(function () use ($count) {
AnalyticsService::logPageView('article_index', $count);
});
return view('articles.index', ['articles' => $articles]);
}
}
?>
Аналитика будет отправлена после того, как пользователь получит страницу:
<html>
<body>
<h1>Articles</h1>
<ul>
<li>Article 1</li>
<li>Article 2</li>
<li>Article 3</li>
</ul>
</body>
</html>