web-dev-qa-db-ja.com

PHPでの構成ファイルの作成

PHPプロジェクト用の設定ファイルを作成したいのですが、これを行うための最善の方法がわからないのです。

これまでに3つのアイデアがあります。

1-変数を使用

$config['hostname'] = "localhost";
$config['dbuser'] = "dbuser";
$config['dbpassword'] = "dbpassword";
$config['dbname'] = "dbname";
$config['sitetitle'] = "sitetitle";

2-定数を使用

define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASSWORD', '');
define('DB_Host', 'localhost');
define('TITLE', 'sitetitle');

-データベースを使用

クラスで設定を使用するので、どちらの方法が最適か、またはより良い方法があるかどうかはわかりません。

82
Ali Akbar Azizi

シンプルだがエレガントな方法の1つは、配列を返すだけのconfig.phpファイル(またはそれを呼び出すもの)を作成することです。

<?php

return array(
    'Host' => 'localhost',
    'username' => 'root',
);

その後:

$configs = include('config.php');
180
Hugo Mota

INIファイルを使用することは、柔軟で強力なソリューションです。 PHPには、適切に処理するための ネイティブ関数 があります。たとえば、次のようなINIファイルを作成できます。

app.ini

[database]
db_name     = mydatabase
db_user     = myuser
db_password = mypassword

[application]
app_email = [email protected]
app_url   = myapp.com

だからあなたがする必要がある唯一のことは電話です:

$ini = parse_ini_file('app.ini');

その後、$ini配列を使用して定義に簡単にアクセスできます。

echo $ini['db_name'];     // mydatabase
echo $ini['db_user'];     // myuser
echo $ini['db_password']; // mypassword
echo $ini['app_email'];   // [email protected]

重要:セキュリティ上の理由から、INIファイルは非パブリックフォルダーになければなりません

54

私は@hugo_leonardoの solution のわずかな進化を使用します:

<?php

return (object) array(
    'Host' => 'localhost',
    'username' => 'root',
    'pass' => 'password',
    'database' => 'db'
);

?>

これにより、$configs->Hostの代わりに$configs['Host']を含めると、オブジェクト構文を使用できます。

また、アプリにAngularアプリのようにクライアント側で必要な設定がある場合、このconfig.phpファイルにすべての設定を含めることができます(1つではなく1つのファイルに集中化されます) JavaScriptとPHP用の1つ)。トリックは、クライアント側の情報のみをechoする別のPHPファイルを持つことです(データベース接続文字列のように表示したくない情報を表示しないようにするため)。 get_app_info.phpと言って呼び出します:

<?php

    $configs = include('config.php');
    echo json_encode($configs->app_info);

?>

config.phpapp_infoパラメーターが含まれていると仮定した場合の上記:

<?php

return (object) array(
    'Host' => 'localhost',
    'username' => 'root',
    'pass' => 'password',
    'database' => 'db',
    'app_info' => array(
        'appName'=>"App Name",
        'appURL'=> "http://yourURL/#/"
    )
);

?>

したがって、データベースの情報はサーバー側に残りますが、アプリの情報にはJavaScriptからアクセスできます。たとえば、$http.get('get_app_info.php').then(...);タイプの呼び出しを使用できます。

23
BoDeX

ここで受け入れられた答えと、それが獲得した賛成票の数にかなり驚いています。 Marcio Mazzucatoによる回答を除いて、複数のアプローチのいずれかの相対的なメリット/弱点についての議論はありません。

私が見るオプションは次のとおりです。

ファイルベースのメカニズム

これらは、iniファイルを見つけるためにコードが特定の場所を探すことを必要とします。これは解決が難しい問題であり、大規模なPHPアプリケーションで常に発生する問題です。ただし、実行時に組み込まれる/再利用されるPHPコードを見つけるには、問題を解決する必要があります。

これに対する一般的なアプローチは、常に相対ディレクトリを使用するか、現在のディレクトリから上方向に検索して、アプリケーションのベースディレクトリで排他的に名前が付けられたファイルを見つけることです。

構成ファイルに使用される一般的なファイル形式は、PHPコード、ini形式のファイル、JSON、XML、YAML、およびシリアル化されたPHPです。

PHPコード

これにより、さまざまなデータ構造を表現するための柔軟性が大幅に向上し、(includeまたはrequireを介して処理されると仮定すると)解析されたコードがオペコードキャッシュから利用可能になり、パフォーマンスが向上します。

include_path は、追加のコードに依存せずにファイルの潜在的な場所を抽象化する手段を提供します。

一方、構成をコードから分離する主な理由の1つは、責任を分離することです。追加のコードをランタイムに注入するためのルートを提供します。

構成がツールから作成された場合、ツール内のデータを検証できる可能性がありますが、HTML、URL、MySQLステートメントに存在するPHPコードに埋め込むためのデータをエスケープする標準機能はありません、シェルコマンド...

シリアル化されたデータこれは、少量の構成(最大約200アイテム)に対して比較的効率的であり、PHPデータを使用できます。構造。データファイルの作成/解析に必要なコードはごくわずかです(そのため、代わりに、適切な承認のみでファイルが書き込まれるように努力することができます)。

ファイルに書き込まれたコンテンツのエスケープは自動的に処理されます。

オブジェクトをシリアル化できるため、構成ファイル(__wakeupマジックメソッド)を読み取るだけでコードを呼び出すことができます。

構造化ファイル

MarcelまたはJSONまたはXMLが示唆するINIファイルとして保存すると、ファイルをPHPデータ構造にマッピングするための簡単なAPIも提供されます(XMLを除き、エスケープするにはシリアル化されたPHPデータを使用してコード呼び出しの脆弱性を排除しながら、データとファイルを作成します。

シリアル化されたデータと同様のパフォーマンス特性があります。

データベースストレージ

これは、大量の設定があり、現在のタスクに必要なものを選択する場合に最もよく考慮されます-約150のデータ項目で、ローカルのMySQLインスタンスからデータを取得するよりも速くなることに驚いたデータファイルのシリアル化を解除します。

OTOHは、データベースへの接続に使用する資格情報を保存するのに適した場所ではありません。

実行環境

実行環境 PHPが実行されている場所で値を設定できます。

これにより、PHPコードが構成の特定の場所を探す必要がなくなります。 OTOHは、大量のデータにうまく対応できず、実行時に普遍的に変更することは困難です。

クライアント上

構成データを保存するために言及していない場所の1つは、クライアントです。繰り返しますが、ネットワークのオーバーヘッドは、これが大量の構成にうまく対応できないことを意味します。エンドユーザーはデータを制御できるため、改ざんが検出可能な形式で(つまり、暗号署名を使用して)保存する必要があり、その開示によって侵害される(つまり、可逆的に暗号化される)情報を含めるべきではありません。

逆に、これにはエンドユーザーが所有する機密情報を保存するための多くの利点があります-サーバーに保存していない場合、そこから盗むことはできません。

ネットワークディレクトリ構成情報を保存するもう1つの興味深い場所は、DNS/LDAPです。これは少数の小さな情報に対して機能しますが、最初の標準形式に固執する必要はありません。たとえば、 SPF を考慮してください。

インフラストラクチャは、キャッシュ、レプリケーション、および配布をサポートしています。したがって、非常に大規模なインフラストラクチャに適しています。

バージョン管理システム

コードなどの構成は、管理およびバージョン管理する必要があります-したがって、VCシステムから直接構成を取得することは実行可能なソリューションです。ただし、多くの場合、これにはかなりのパフォーマンスオーバーヘッドが伴うため、キャッシュを使用することをお勧めします。

19
symcbean

まあ-データベース構成データをデータベースに保存するのはちょっと難しいでしょう-思いませんか?

しかし、実際には、これは非常に意見が多い質問です。どのスタイルも実際に機能し、好みの問題だからです。個人的には、定数ではなく構成変数を使用します。一般的に、必要な場合を除き、グローバル空間の物は好きではないからです。私のコードベースのどの関数も、データベースパスワードに簡単にアクセスできないはずです(データベース接続ロジックを除く)。そこで、そこで使用してから破棄する可能性があります。

編集:コメントに答えるために-解析メカニズムはどれも最速ではありません(ini、jsonなど)そのような小さなファイルでは速度の違いは無視できるため、最適化について。

6
Colin M

Defineは、グローバルを使用する必要なく、クラス内のどこでも定数を使用可能にします。変数はクラス内でグローバルを必要としますが、DEFINEを使用します。ただし、プログラムの実行中にdb paramsを変更する必要がある場合は、変数に固執することをお勧めします。

2
phpalix

静的プロパティの設定クラスを作成できます

class Config 
{
    static $dbHost = 'localhost';
    static $dbUsername = 'user';
    static $dbPassword  = 'pass';
}

その後、簡単に使用できます:

Config::$dbHost  

私のプロジェクトでは、デザインパターンSINGLETONを使用して構成データにアクセスすることがあります。とても快適に使用できます。

どうして?

たとえば、プロジェクトに2つのデータソースがあります。そして、それらの魔女が有効になっていることを選択できます。

  • mysql
  • json

選択した設定ファイルのどこか:

$dataSource = 'mysql' // or 'json'

ソース全体のアプリを新しいデータソースに切り替える必要がある場合、問題なく動作し、コードを変更する必要はありません。

例:

構成:

class Config 
{
  // ....
  static $dataSource = 'mysql';
  / .....
}

シングルトンクラス:

class AppConfig
{
    private static $instance;
    private $dataSource;

    private function __construct()
    {
        $this->init();
    }

    private function init()
    {
        switch (Config::$dataSource)
        {
            case 'mysql':
                $this->dataSource = new StorageMysql();
                break;
            case 'json':
                $this->dataSource = new StorageJson();
                break;
            default:
                $this->dataSource = new StorageMysql();
        }
    }

    public static function getInstance()
    {
        if (empty(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function getDataSource()
    {
        return $this->dataSource;
    }
}

...そしてコードのどこか(例:サービスクラス):

$container->getItemsLoader(AppConfig::getInstance()->getDataSource()) // getItemsLoader need Object of specific data source class by dependency injection

システム内の任意の場所からAppConfigオブジェクトを取得し、常に同じコピーを取得できます(静的のおかげです)。クラスのinit()メソッドはコンストラクターで呼び出され、1回の実行のみを保証します。 Init()本体はconfig $ dataSourceの値をチェックし、特定のデータソースクラスの新しいオブジェクトを作成します。これで、スクリプトはオブジェクトを取得して操作できるようになり、実際にどの特定の実装が存在するかを知ることもできません。

2

何らかの理由で複数のdbを使用すると思われる場合は、1つのパラメーターを変更してまったく異なるdbに切り替えることができるため、変数を使用します。つまりテスト、自動バックアップなどのために.

2
trigun0x2

通常、データベース接続を持つ単一のconn.phpファイルを作成します。次に、データベースクエリを必要とするすべてのファイルにそのファイルを含めます。

1
Mihir Chhatre

これが私のやり方です。

<?php

define('DEBUG',0);

define('PRODUCTION',1);



#development_mode : DEBUG / PRODUCTION

$development_mode = PRODUCTION;



#Website root path for links

$app_path = 'http://192.168.0.234/dealer/';



#User interface files path

$ui_path = 'ui/';

#Image gallery path

$gallery_path = 'ui/gallery/';


$mysqlserver = "localhost";
$mysqluser = "root";
$mysqlpass = "";
$mysqldb = "dealer_plus";

?>

疑問がある場合はコメントしてください

0