[英]PHP Scope, $GLOBALS & Singletons
我很難獲得一些非常基本的PHP問題的答案。 我觀看過的視頻教程都是針對使用 PHP的服務器端腳本的基礎知識,但實際上很少解釋PHP如何工作。
假設我們有2個用戶同時連接到來自世界不同地區的同一個LAMP服務器,並且都在請求Widget.php。
(a)Apache / PHP如何有效地“復制”Widget.php腳本及其依賴項的2個實例,以便分別處理2個HTTP請求?
(b)根據上面的(a)部分,PHP如何划分用戶請求以使它們分開? 如果Widget.php使用名為$_SESSION['cheese']
的會話變量,那么PHP如何將2個用戶的奶酪價值分開?
(c)PHP $GLOBALS
用戶范圍還是應用程序范圍的? 這意味着,對於全局var $GLOBALS['bread']
,用戶1和2是否共享相同的引用,或者PHP是否將它們與(b)中的會話變量分開?
(d)PHP $GLOBALS
變量與實現單例設計的對象有什么區別? 如果應用程序只能訪問單例的1個實例,那么它不是全局的嗎? 是否應考慮性能因素?
將php應用程序視為每次服務器請求時執行的腳本,而不是服務器內存中存在的應用程序。 當HTTP請求進入時,腳本運行,因此$ _SESSION ['cheese']對於請求它的用戶是唯一的,因為會話ID存儲在客戶端瀏覽器cookie中。
全局變量只是具有腳本范圍的變量,因此對於發送HTTP請求腳本的用戶來說,它們是相同的。 單例是一個只能有一個實例並且與全局不同的類。
PHP腳本是無狀態的,因為當腳本完成執行時,對象保持的所有值都將丟失。 使對象在執行之間保持持久的唯一方法是序列化到數據庫或會話或文件系統。
(a)PHP像大多數其他CGI實現一樣運行。 當Web服務器收到對恰好是.cgi / .php腳本的特定URL的請求時,將使用引用的腳本調用解釋器。 PHP解釋器運行它,並將輸出發送回Web服務器/客戶端。 完成后,該CGI解釋器終止並使用它獲取所有運行時數據。
這就解釋了為什么變量不會持久存在或在兩個不同的PHP腳本或調用之間共享。 它對於普通的mod_php處理程序也是一樣的。 只有它的簡單過程分叉(復制)和終止。
(b)$ _SESSION數組由PHP處理。 它可以使用唯一的cookie密鑰識別每用戶存儲。 由於每個CGI或mod_php進程都有一個單獨的變量池,因此確實沒有問題。 PHP只需要一些文件鎖定,以防止兩個腳本在同一個用戶同時請求兩個腳本時覆蓋會話存儲。
(c)“全局”變量也只存在於每個過程中。 當PHP腳本完成時,它們就像其他一切一樣消失了。
(d)這是兩個不同的概念。 我看到你對用法的相似之處是什么意思。 但全局變量只是一個共享范圍,可能更接近於價值對象。 您可以使用全局標識符訪問它們,但這是相似之處。
a)你問的是apache / php是如何工作的? 這是雄心勃勃的......長話短說:php會在每個請求上編譯Widget.php,而apache會在Http協議上發送響應
b)你的服務器會將SESSION數據保存在數據庫或文件或神奇的地方(真的不知道它在哪里以及如何做,所有我關心的是它被保存)。 在每個請求中,瀏覽器將發送一個會話cookie,其中包含PHP將用於將適當的信息加載到$ _SESSION變量中的會話ID。 (就像數據庫表上的主鍵一樣)
c)它是用戶范圍(腳本端),但它不會像會話這樣的頁面之間保留。
d)$ GLOBALS是一個變量,單例是一個具有屬性,方法,訪問器,可以繼承,覆蓋等的對象
祝好運!
對於B,用戶持有一個名為UUID的唯一ID,它存儲在cookie中。 所以服務器可以通過讀取這個唯一的ID來區分用戶並返回適當的會話值。
$ GLOBALS是應用程序范圍。
單例對象在某種程度上是全局的,但你不一定有一個實例,在具體時刻存在......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.