Tente obter um singleton real do Laravel:
- Classe de serviço:
<?php
namespace App\Services;
use Illuminate\Support\Facades\Log;
class SingleTest
{
public function __construct(
public string $var
) {
Log::info('init instance');
}
}
- Registre este serviço como singleton:
<?php
namespace App\Providers;
use App\Services\SingleTest;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(SingleTest::class, fn() => new SingleTest('test singleton'));
}
}
- Minhas rotas para verificação (web.php):
Route::get('/test1', fn() => app(SingleTest::class)->var);
Route::get('/test2', fn() => app(SingleTest::class)->var);
Então eu faço o curl das rotas /test1 e /test2:
- enrolar as impressões
test singleton
duas vezes - bom. - com log espero que o construtor seja chamado apenas uma vez e
init instance
apareça uma vez. Não, vejo 2 mensagens que significam que a segunda instância de SingleTest também foi criada. Não é um singleton.
PHP é uma "Arquitetura Sem Compartilhamento", singletons não persistem em requisições HTTP, já que o aplicativo é inicializado do zero em cada requisição.
Você pode usar o Laravel Octane se quiser persisti-los entre solicitações, já que ele inicializa seu aplicativo uma vez (por trabalhador), permitindo que várias solicitações compartilhem o mesmo singleton até que o trabalhador seja reiniciado ou coletado como lixo.