2017-09-28 16 views
1

私は1年前に書いた非常に大きなPHPアプリケーションを書き直す機会があり、私はアプリケーション構成を実装するためのアイデアを探しています。PHP設定クラスと従属クラスのベストプラクティス

現在、私はきれいにし、簡単に私のPHPコードでアクセス設定パラメータをすることができます私の大規模な(と読める非常に人間)config.phpファイルを読み込み、設定クラスを持っています。この設定オブジェクトは、_init.phpスクリプトの変数としてインスタンス化されています。簡略化されたサンプルは以下の通りです:

<?php 
    class Configuration { 
    public $someConfigProperty = true; 
    public const someOtherConstant = false; 
    } 

    // _init.php 
    $CONFIGURATION = new Configuration; 
?> 

これは私がグローバルとして$CONFIGURATION変数を宣言する必要があり、他のすべてのクラスのすべてのメソッドでことを除いて、うまく動作します。私が代わりにしたいのは、コンフィグレーションオブジェクトにアクセスする必要がある他のすべてのクラスがConfigurationクラスを拡張するだけです。このような何か:

<?php 
    class Configuration { 
    public $someConfigProperty = 'some string'; 
    public const someOtherConstant = false; 
    } 

    class Foo extends Configuration { 
    public static function getConfigProperty() { 
     return $this->someConfigProperty; 
    } 
    } 
?> 

私の質問です:これは悪い考えです、そしてなぜか?私はこれをやってはいけない技術的な理由やこれを悪い考えにする将来の保守性についての懸念を探しています。

答えて

2

はい、これはおそらく悪い考えです。一般に、他のクラスを拡張するクラスは、特殊化関係を意味します。典型的な例は、Cat extends MammalSquare extends Rectangleです。どちらの場合も、前者は後者の特殊化です。したがって、Fooが特殊な設定でない限り、Configurationを拡張しないでください。

ここで必要なのは「依存性注入」です。それはGoogleです。一方、いくつかの素晴らしいPHPのクラスがある(のようなthis one)はこのように、あなたに瞬時に注入を与えるために:魔法のよう

class Foo { 
    public function __construct(Configuration $config) { 
     echo $config->getConfigProperty(); 
    } 
} 

、DIライブラリが作ること、それを組み込むの単なる行為によって、自動的に利用可能Configurationオブジェクトあなたの署名で。

これはDIを実行する方法の1つです。他にもあります。 Googleの "php dependency injection"では、さまざまな方法の良いアイデアが得られます。

0

私は通常、このようなパターンを使用し、各サービスごとに1つずつ、さまざまな設定ファイルを用意しています。この例では、PostgreSQLのためにある:

1.

は、アプリケーションが実行する各環境に1つのファイルを持つ個々の環境ファイルを用意しますが、名前を付け、何か一般的なようconfig.local.php。そのファイルをサーバー上に永久に置くか、または展開中にフック/ポストデプロイメントスクリプトなどを使用して、アクセスできない環境フォルダから通常の設定フォルダに関連する場所にコピーします。ファイル形式は次のようになります。

define("POSTGRESQL_DATABASE", "mydatabasename"); 
define("POSTGRESQL_USERNAME", "myusername"); 
define("POSTGRESQL_PASSWORD", "itsasecret"); 
define("POSTGRESQL_SERVER_IP", "localhost"); 

あなたはこのようにフォルダ構造を持っているかもしれません:

-config 
-environments 
    -test 
    -config 
    -prod 
    -config 
-public_html 

...と展開後のフックで/config//environments/prod/config/の内容をコピーします。

(おそらく別の安全なリポジトリからそれらをコピー?)理想的には、あなたのメインのソースコントロールのうち、設定ファイルを続けるだろうし、代わりに各サーバーでそれらを個別に作成

このファイルには、中に/config/から含まれることになりますあなたの初期化プロセス。

2.

は、これらの定数

を使用してConfigurationクラスを作成しますセッターがプライベートであること(およびコンストラクタで呼ばれる)とゲッターは、公開された状態でお使いの設定変数を保持しているコンフィギュレーション・クラスを作成します。

class PostgreSQLDatabaseConfiguration 
{ 
    private $databaseName = null; 
    private $password = null; 
    private $serverIP = null; 
    private $username = null; 
    #endregion 

    #region Public methods 
    final public function __construct($serverIP, $databaseName, $username, $password) { 
     $this 
      ->setServerIP($serverIP) 
      ->setDatabaseName($databaseName) 
      ->setUsername($username) 
      ->setPassword($password); 
    } 

    /** 
    * @return string 
    */ 
    public function getDatabaseName() { 
     return $this->databaseName; 
    } 

    public function getPassword() { 
     return $this->password; 
    } 

    public function getServerIP() { 
     return $this->serverIP; 
    } 

    public function getUsername() { 
     return $this->username; 
    } 
    #endregion 

    #region Private methods 
    private function setDatabaseName($databaseName) { 
     $this->databaseName = $databaseName; 
     return $this; 
    } 

    private function setPassword($password) { 
     $this->password = $password; 
     return $this; 
    } 

    private function setServerIP($serverIP) { 
     $this->serverIP = $serverIP; 
     return $this; 
    } 

    private function setUsername($username) { 
     $this->username = $username; 
     return $this; 
    } 
    #endregion 
} 

3.コンフィギュレーションクラスを生成共通構成ファイルを持っている

このファイルには、すべての環境に共通するだろう(すなわち、あなたの標準的な展開の一部を構成する)と、前のステップから定義された定数を使用して、構成オブジェクトのインスタンスを作成します:

include('/config/config.local.php');  
$postgresqlDatabaseConfiguration = new PostgreSQLDatabaseConfiguration(
    POSTGRESQL_SERVER_IP, 
    POSTGRESQL_DATABASE, 
    POSTGRESQL_USERNAME, 
    POSTGRESQL_PASSWORD 
); 

あなたの構成オブジェクトは、あなたのDatabaseAccessorでクラスに注入する準備ができました、そして、あなたのメインのコードベースがあります環境に依存しない。

関連する問題