2009-05-19 56 views
2

我有類似下面的一些PHP代碼:「命名空間」,常量和多個PHP包括

foreach ($settingsarray as $settingsfile) 
{ 
    include ($settingsfile); 
    // do stuff here 
} 

$ settingsarray是文件名從特定文件夾中的數組。

問題是,每個$ settingsfile定義的常量(具有相同的名稱),當然,這是不能重新定義的。

有什麼可能的方法來防止在這種情況下發生錯誤?

我能想到的兩個選項包括將所有常量改爲變量並使用PHP命名空間。

但是,我不知道如何去使用名稱空間,它需要在每個$ settingsfile的開始聲明?有沒有使用名稱空間隔離常量,可執行文件和函數的方法?

我真的很喜歡,是能夠做簡單的東西:

foreach ($settingsarray as $settingsfile) 
{ 
    {//added braces to indicate where the isolation is 
     include ($settingsfile); 
     // do stuff here 
    }//what happens in here does not affect what happens outside of here 
} 

我應該注意,這是一個新的功能的一部分,並且是代碼的唯一部分加載所有$ settingsfiles。其餘的代碼一次只加載一個文件。我使用常量的一個原因是,我不必擔心將變量「全局」定義爲能夠在函數內部訪問它們。

回答

1

好吧,如果我正確地理解了你,那麼在這個循環中,你想用每個$settingsfile中定義的常量來做事情,然後基本上在每次循環後襬脫它們?

與變量不同,一個不變的是,一旦設置的值,不能在您的腳本執行 src

你唯一的選擇就是改變define()聲明變量過程中改變或取消。

+0

你有我想要做的正確。解決方案,我不想聽到。 (程序實際上非常複雜,這個代碼來自一個新的特性,其餘的代碼只在特定的時間加載一個設置文件,把所有的常量改爲變量將意味着改變所有的休息的代碼以及...) – Alya 2009-05-19 14:19:46

1

不容易,但您可以用file_get_contents($ settingsfile)讀取php文件,然後重寫常量並評估代碼。

$settingsstr = file_get_contents($settingsfile); 
$settingsstr = preg_replace('/<\?\w*(.*)/', '\\1', $settingsstr);//get rid of the php open tag 
$settingsstr = preg_replace('/define\("(\w+)"/', 'define("NAMESPACE_\\1"', $settingsstr); 
eval($settingsstr); 
+2

這只是尖叫「可怕的糟糕的黑客」 – nickf 2009-05-19 13:56:18

1

您有幾種選擇:

使用PHP命名空間

出人意料的是,PHP實際上確實有namespaces支持。我很驚訝地發現這一點,因爲我一直在PHP工作多年,從未聽說過這個功能。這可能是一個新的特點,一個是不常用的,所以我不會使用這種方法

使用類常量

你可以使用類和class constants加載您的設置建議。類常量是定義類的局部屬性,因此您不必擔心類中的名稱衝突。您可能需要做的不僅僅是包含文件,而是可以在每個類上調用一個方法,比如定義應用常量的defineConstants()或loadConfiguration(),並保持類常量供內部使用。

使用函數來擴展設置

另一個想法是創建一個設置陣列和單獨的函數來「擴展」的那些設置。這樣,您可以在後續函數中覆蓋任何配置而不會導致錯誤。最後,如果你想把它們放在常量中,你可以遍歷數組並使用define()來定義常量。

還有很多其他方法可以完成您正在嘗試做的事情,但這些只是一些想法。

+0

命名空間是PHP 5.3中的新功能,但尚未穩定發佈。 – nickf 2009-05-19 13:58:19

0

設置文件不應該包含PHP代碼。 它應該是某種「標準」格式。 http://www.php.net/parse_ini_file

  • 在第一步中(在你的foreach)你看過的所有文件
  • 收集變量放入一個臨時數組
  • 在另一個遍歷數組,你可以將它們定義爲常量。

如果您經常感覺需要「重新定義常量」,那麼在應用程序設計中就會出現一些問題。

+1

我不認爲在PHP中定義的設置本質上沒有任何問題。我不希望最終用戶結束這些設置文件,但對我直接在PHP中編寫設置的效率要高得多。 – nickf 2009-05-19 14:05:18

4

我的答案有點複雜,但應該很適合你。我假設你有很多這些設置文件,因爲你很難單獨更改每一個。

如果你能夠使用命名空間,我假設你已經升級到PHP 5.3RC2。複製下面的成PHP文件,並更改命名空間,以自己的喜好:

<?php 
namespace myapp\config; 

function define($key, $val) { 
    Config::set($key, $val); 
} 

class Config { 
    private $vars = array(); 

    // This class should not be instantiated 
    private function __construct() {} 

    public function set($key, $val) { 
     self::$vars[$key] = $val; 
    } 

    public function get($key) { 
     return isset(self::$vars[$key]) ? self::$vars[$key] : NULL; 
    } 
} 

?> 

包括在你的代碼,現在讓一切的工作是改變

<?php 

一個簡單的事情您的設置文件

<?php namespace myapp\config; 

如果你有一噸的人,在你的終端快速「sed的」命令應該照顧它很好地,所有的一舉。

如果我失去你如何使用我的代碼,這裏有一個例子:

<?php 
require_once('the_php_file_i_just_gave_you.php'); 
use \myapp\config\Config; 

foreach ($settingsarray as $settingsfile) { 
    include ($settingsfile); 
    $varname = 'key'; 
    echo "In this file, '$varname' equals: " . Config::get($varname); 
} 

?> 

祝你好運!