2014-03-12 33 views
2

我對PHP比較陌生,我正在尋找一種方法來定義某些對象,這些對象可以在整個項目中從多個PHP腳本全局訪問。整個項目中的PHP全局變量

在Java中,如果我在全球範圍內訪問某些對象,我定義一個名爲Globals一些公共類,並定義我需要訪問爲靜態Globals類的對象。然後,我隨時隨地訪問這些對象:Globals.variable_name

所以基本上,我只需要一次初始化這些全局對象,然後每當我需要他們使用它們..

一個用例:

我有一個名爲Logger類有方法在日誌文件中記錄某些事件。我需要有1 Logger實例/對象,可以在項目中的所有PHP腳本中使用,只要他們必須記錄一些內容。我寧願沒有使用它自己的Logger實例的每個PHP腳本。

天真類似Java的方法我試過了,沒有工作:

我創建了一個單獨的PHP文件(名爲Globals.php)命名Globals公共類類型的一個靜態對象Logger,名稱爲$logHandle。我將這個PHP文件包含在所有其他需要此Logger對象的PHP文件中。然後我嘗試使用來自其他PHP腳本之一的Globals->logHandle訪問此對象。這種嘗試失敗了。

有沒有類似的方法?

謝謝。

+2

相關 - [爲什麼globals是邪惡的](http://stackoverflow.com/a/5166527/1607098)。嘗試使用[依賴注入](http://en.wikipedia.org/wiki/Dependency_injection)代替 – Touki

+0

如果沒有在頁面上實例化對象而不能訪問成員數據,我會建議在類Globals中使用靜態變量並使用他們作爲包含文件中的Globals :: varname。 –

+0

請記住,在Java中,您的靜態實例實際上是在不同的servlet之間共享的,因爲它們運行在同一個VM中,而在PHP中,您可以共享定義和代碼來創建實例,但是您沒有共享**狀態**腳本之間。 –

回答

4

PHP不是Java。

在Web應用程序中,PHP環境針對每個請求進行初始化 - 並且每個請求都使用自己的內存空間在不同的進程中處理。跨不同實例共享對數據(包括序列化對象,但不包括數據庫連接和文件句柄等資源)的訪問是可能的。您可能已經知道這一點,但尚未意識到它會如何影響您編寫代碼的方式。

我寧願沒有每個PHP腳本使用它記錄儀

爲什麼不是自己的實例?

一個非常好的理由是,允許多個進程寫入同一個打開的文件句柄需要鎖定以防止文件全部搞定。但這是PHP - 停止從SCRATCH重新獲得一些東西。寫入stderr會將詳細信息附加到Web服務器錯誤日誌或使用操作系統syslog工具 - 這就是它們的用途。

不可能將相同的對象用於PHP的所有實例 - 您可以在所有實例中反序列化對象 - 但它們不是同一個對象。您可以使用單個對象運行守護程序,該對象可以通過套接字連接訪問所有其他PHP實例 - 但它不在同一地址空間中運行。

如果您有效地有一個類,您希望通過具有固定名稱的對象通用,那麼只需在每個腳本中或通過包含文件創建對象的實例即可。你嘗試的方法是解決這個問題的方法(但不要用保留字命名你的對象)。我們不知道它爲什麼失敗,因爲您沒有提供任何錯誤消息或代碼。

0

要訪問PHP,你需要與Class::$attribute符號稱之爲靜態屬性,靜態方法需要與Class::method()符號調用。當調用類實例的屬性時,使用->表示法。

1

你可以像這樣 你說,你已經在所有其他類改變全局類的方法,以靜態

<?php 
class Logger { 
    public static function log($msg) { 
     // ... 
    } 
} 

,你可以使用它像

Logger::log($msg); 
1

我想你'正在問一些常見的案例(現在只有面向Web的應用)。對於這一點 - 不,你不能定義一些你所描述的東西,在原生的方式。這是在PHP中被稱爲superglobals的東西。

但另一方面 - 你需要這樣做,而不是「只是因爲你想要它」。而且,如果是這樣 - 那麼使用配置文件。創建一些應用程序配置文件,在應用程序啓動時(bootstrap)讀取一次,您將獲得所有需要的值。我沒有提到任何關於文件結構的東西 - 它可以是xml/ini/yaml/whatever/you/like。但是這個想法是 - 從應用程序結構本身分離出這個邏輯,並使用單獨的文件來存儲所需的值。

另一種選擇是使用一些單獨的PHP文件並將其包含在引導程序中。定義該文件中所有需要的變量/常量,您將得到類似的行爲。請注意,就名稱空間而言,它不太「全局」,您需要手動解決所有這些情況。

但是,對於網絡應用程序,可能的解決方案之一可能使用sessions$_SESSION是一個超全球數組,它會表現得像你想要的(即將從任何地方訪問)。但這並不總是適用 - 並不總是你想要處理會話來存儲會話無關的數據。

+0

我認爲重點實際上只是在創建記錄器的代碼中放置一個位置,而不必在整個位置寫入'$ logger = new Logger()'。 –

+0

我已經從_「定義某些對象作爲整個項目的全局可訪問性來做出我的假設」_ –

+0

實際上,我曾嘗試過'$ GLOBALS',但這也只適用於腳本內的所有類,但不跨越多個文件。我會嘗試'$ _SESSION',但我認爲這將在一個腳本內受到限制。是的,我認爲作爲最後的手段,我將不得不使用一些外部配置文件。 –