This sounds like a perfect opportunity to make use of Laravels queues, which also allow for delayed dispatching as you can find in the documentation when looking for queuing and delayed dispatching.
Basically, you will need a job that you can push onto the queue like the following
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class RemoveFileFromFtp implements ShouldQueue
{
use Dispatchable, Queueable;
protected $file;
/**
* Create a new job instance.
*
* @param string $file
* @return void
*/
public function __construct(string $file)
{
$this->file = $file;
}
/**
* Execute the job.
*
* @param FtpService $ftpService
* @return void
*/
public function handle(FtpService $ftpService)
{
$ftpService->removeFileIfExists($this->file);
}
}
You will then be able to dispatch the job like so:
function doSomethingWithFileOnFtp()
{
// ... here you can do what you described
// and then you queue a clean up job for the file
RemoveFileFromFtp::dispatch($file)->delay(now()->addMinutes(30));
}
Of course this solution expects you to have set up Laravel queues properly. There is different ways you can do this, but I guess the documentation is your best friend regarding this (see here).