115

PHPプロジェクトの構成ファイルを作成したいのですが、これを行うための最良の方法がわかりません。

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

1-変数を使用する

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

2-Constを使用する

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

3-データベースを使用する

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

4

13 に答える 13

248

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

<?php

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

その後:

$configs = include('config.php');
于 2013-02-07T13:44:57.183 に答える
93

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

app.ini

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

[application]
app_email = mailer@myapp.com
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'];   // mailer@myapp.com

重要:セキュリティ上の理由から、INIファイルは非公開フォルダにある必要があります

于 2015-12-07T14:03:01.863 に答える
28

@hugo_leonardoのソリューションのわずかな進化を使用します:

<?php

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

?>

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

また、アプリにクライアント側で必要な構成がある場合(Angularアプリの場合など)、このconfig.phpファイルにすべての構成を含めることができます(JavaScript用とPHP用ではなく1つのファイルに一元化されます)。その場合の秘訣は、クライアント側の情報のみを含む別のPHPファイルを作成するechoことです(データベース接続文字列のように表示したくない情報が表示されないようにするため)。それを言うget_app_info.php

<?php

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

?>

上記は、パラメータconfig.phpが含まれていると仮定しています。app_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(...);ある種の呼び出しがあります。

于 2016-10-16T06:08:10.257 に答える
25

相対的な長所/短所で私が見るオプションは次のとおりです。

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

これらでは、コードが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データ構造にマップする(XMLを除いて、データをエスケープしてファイルを作成する)ための単純なAPIも提供されますシリアル化されたPHPデータを使用した脆弱性。

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

データベースストレージ

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

OTOHは、データベースへの接続に使用するクレデンシャルを保存するのに適した場所ではありません。

実行環境

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

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

クライアントで

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

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

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

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

バージョン管理システム

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

于 2017-07-13T16:57:43.240 に答える
6

ええと、データベース構成データをデータベースに保存するのはちょっと難しいでしょうね。

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

編集:コメントに答える-解析メカニズムはどれも最速ではありません(ini、jsonなど)-しかし、速度の違いが原因で最適化に本当に集中する必要があるアプリケーションの部分でもありませんこのような小さなファイルでは無視できます。

于 2013-02-07T13:43:29.817 に答える
4

configclasswitch静的プロパティを作成できます

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()本体は、構成$ dataSourceの値をチェックし、特定のデータソースクラスの新しいオブジェクトを作成します。これで、スクリプトはオブジェクトを取得して操作できるようになり、実際にどの特定の実装が存在するかさえわかりません。

于 2017-10-18T11:31:03.017 に答える
2

定義は、グローバルを使用せずにクラス内のどこでも定数を使用できるようにしますが、変数はクラス内でグローバルを必要としますが、私はDEFINEを使用します。ただし、プログラムの実行中にdb paramsが変更された場合は、変数を使用することをお勧めします。

于 2013-02-07T13:43:01.913 に答える
2

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

于 2013-02-07T13:44:04.773 に答える
1

これが私のやり方です。

    <?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";

   ?>

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

于 2015-04-13T06:37:11.263 に答える
0

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

于 2013-02-07T13:41:14.897 に答える
0

このようなものはどうですか?

class Configuration
{

    private $config;

    
    public function __construct($configIniFilePath)
    {
        $this->config = parse_ini_file($configIniFilePath, true);
    }

    /**
     * Gets the value for the specified setting name.
     *
     * @param string $name the setting name
     * @param string $section optional, the name of the section containing the
     *     setting
     * @return string|null the value of the setting, or null if it doesn't exist
     */
    public function getConfiguration($name, $section = null)
    {
        $configValue = null;

        if ($section === null) {
            if (array_key_exists($name, $this->config)) {
                $configValue = $this->config[$name];
            }
        } else {
            if (array_key_exists($section, $this->config)) {
                $sectionSettings = $this->config[$section];
                if (array_key_exists($name, $sectionSettings)) {
                    $configValue = $sectionSettings[$name];
                }
            }
        }

        return $configValue;
    }
}
于 2021-01-09T14:56:30.200 に答える
0

config.confのような設定ファイルがある場合(htttp://example.com/config.confの場合もあります)

user=cacom
version = 2021608
status= true

これは私の機能です:

function readFileConfig($UrlOrFilePath){

    $lines = file($UrlOrFilePath);
    $config = array();
    
    foreach ($lines as $l) {
        preg_match("/^(?P<key>.*)=(\s+)?(?P<value>.*)/", $l, $matches);
        if (isset($matches['key'])) {
            $config[trim($matches['key'])] = trim($matches['value']);
        }
    }

    return $config;
}

使用できます:

$urlRemote = 'http://example.com/default-config.conf';
$localConfigFile = "/home/domain/public_html/config.conf";
$localConfigFile2 = "config.conf";

print_r(readFileConfig($localConfigFile2));
print_r(readFileConfig($localConfigFile));
print_r(readFileConfig($urlRemote));
于 2021-06-08T05:46:36.870 に答える
0

この単純なものを使用できます:

define('someprop', 0);

echo someprop;//出力0

于 2021-12-15T09:03:51.690 に答える