儘管曼塔斯在大多數情況下都是正確的,但說明生命期是單一請求可能會在某些邊緣情況下產生誤導。
基本上,服務容器的壽命只要內核生活。服務容器在Kernel::boot()
期間被初始化,這被稱爲內核首次處理請求。 (例如,請參閱您的前端控制器app.php。)容器在Kernel::shutdown()
或PHP進程退出時被丟棄。因此,當你讓你的內核處理多個請求,或者當你在你的內核生命週期中做子請求時,服務容器仍然存在,並且你的服務中的任何狀態都被保留下來。
就拿下面的兩段代碼:
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$responseOne = $kernel->handle($requestOne); // Container initialised
$responseOne->send();
$kernel->terminate($requestOne, $responseOne);
$responseTwo = $kernel->handle($requestTwo); // Container still exists
$responseTwo->send();
$kernel->terminate($requestTwo, $responseTwo);
$kernel->shutdown(); // Container destructed
而且
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$responseOne = $kernel->handle($requestOne); // Container initialised
$responseOne->send();
$kernel->terminate($requestOne, $responseOne);
$kernel->shutdown(); // Container destructed
$responseTwo = $kernel->handle($requestTwo); // New Container initialised
$responseTwo->send();
$kernel->terminate($requestTwo, $responseTwo);
// PHP exits, container destructed
在大多數情況下,你的PHP理線將有一個請求到Web服務器的使用壽命。但是,在某些情況下,您可以利用這種能力在請求之間保持包含服務容器的內核。例如,有基本保持內核活動的php-pm project,並在其上激發請求。
這樣可以提高性能(不需要爲每個請求重複構建容器和初始化bundle)。另一方面,您的服務將爲多個請求共享,可能爲多個用戶共享,這意味着在您的服務中保存狀態可能會帶來很大的安全風險。
因此,請務必將您的數據類與您的服務分開,並且不要將數據存儲在您的服務中。 Symfony就是一個很好的例子,它使用Request和Response類來分離數據。
當你說>>「共享服務意味着每次訪問服務時都會返回相同的實例」,你的意思是在同一個請求中 - 因爲他們是我理解的同一個服務容器的一部分? 2個消費者,我的意思是1是一個控制器,直接訪問依賴性D1方法,並通過D2訪問D1。當'shared'是'false'時,我觀察到兩者都是不同的狀態。但是當'shared'是'true'時,它的狀態是相同的。 – Chinmay
是的,我的意思是「在同一個請求中」。 Symfony不會在請求之間共享任何內容(除非將某些內容明確地存儲在cookie,會話,某個數據庫或任何其他存儲中)。 – Mantas
看到我的試驗和您的回覆,我會將答案標記爲已接受。謝謝。我還有一個問題 - 如果我們可以使用註釋將服務指定爲共享。但我想這裏還有另一個問題。 – Chinmay