Membuat file konfigurasi di PHP

101

Saya ingin membuat file konfigurasi untuk proyek PHP saya, tetapi saya tidak yakin apa cara terbaik untuk melakukannya.

Saya punya 3 ide sejauh ini.

Variabel 1-Penggunaan

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

2-Gunakan Const

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

3-Gunakan Database

Saya akan menggunakan konfigurasi di kelas jadi saya tidak yakin cara mana yang terbaik atau ada cara yang lebih baik.

Ali Akbar Azizi
sumber
12
4) Gunakan file ini. 5) Gunakan file YAML. 6) Gunakan file JSON. 7) ... Ada begitu banyak cara ... Tentukan beberapa kriteria untuk dinilai setidaknya, tidak ada yang "terbaik" secara keseluruhan.
menipu
@deceze apa cara berpuasa? (ingatan dan cepat)
Ali Akbar Azizi
Ini akan menjadi bacaan yang menarik untuk Anda: stackoverflow.com/questions/823352/…
eithed
1
Saya menggunakan cara Laravel melakukannya (jika tidak menggunakan Laravel). Saya membuat kelas yang memuat file konfigurasi tertentu tergantung pada nama host. Saya kemudian menyebutnya dengan menggunakan Config::get('key');. pastebin.com/4iTnjEuM
MisterBla

Jawaban:

218

Salah satu cara sederhana namun elegan adalah membuat config.phpfile (atau apa pun sebutan Anda) yang hanya mengembalikan array:

<?php

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

Lalu:

$configs = include('config.php');
Hugo Mota
sumber
10
Saya juga suka metode ini - saya pikir ini lebih bersih daripada hanya mendeklarasikan variabel dalam file yang disertakan dan mengasumsikan itu akan ada di skrip Anda
Colin M
Di manakah metode jawaban untuk membuat file konfigurasi ini? Untuk php pemula seperti saya?
Luka
@Luka Anda dapat menggunakan fungsi var_export .
Hasan Bayat
77

Gunakan file INI adalah solusi yang fleksibel dan kuat! PHP memiliki fungsi asli untuk menanganinya dengan baik. Misalnya, dimungkinkan untuk membuat file INI seperti ini:

app.ini

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

[application]
app_email = mailer@myapp.com
app_url   = myapp.com

Jadi satu-satunya hal yang perlu Anda lakukan adalah menelepon:

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

Kemudian Anda dapat mengakses definisi dengan mudah menggunakan $inilarik.

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

PENTING: Untuk alasan keamanan, file INI harus berada di folder non publik

Marcio Mazzucato
sumber
Apakah ini juga aman digunakan? Jika pengguna menebak jalur ke file ini, dan pergi ke sana di browser mereka, akankah mereka melihat apa yang ada di file?
NickGames
1
@NickGames, Anda harus meletakkan file di folder non publik, jika tidak Anda akan berada di bawah risiko keamanan yang serius
Marcio Mazzucato
2
@NickGames, silakan lihat 1 komentar di Docs of parse_ini_file ()
R Picheta
19
Saya suka pendekatan ini. Tip bonus: Ubah nama file menjadi app.ini.php. Kemudian tambahkan ke baris pertama ;<?php die(); ?>. Jika file ini tidak sengaja muncul di folder publik, itu akan diperlakukan sebagai file PHP dan mati pada baris pertama. Jika file dibaca dengan parse_ini_file, itu akan memperlakukan baris pertama sebagai komentar karena ;.
andreas
1
Catatan: Jika nilai dalam file ini berisi karakter non-alfanumerik apa pun, nilai itu harus diapit oleh tanda kutip ganda ( "). Misalnya, kata sandi apa pun berisi karakter non-alfanumerik.
Key Shang
24

Saya menggunakan sedikit evolusi dari solusi @hugo_leonardo :

<?php

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

?>

Ini memungkinkan Anda untuk menggunakan sintaks objek saat Anda menyertakan php: $configs->hostalih-alih$configs['host'] .

Selain itu, jika aplikasi Anda memiliki konfigurasi yang Anda perlukan di sisi klien (seperti untuk aplikasi Angular), Anda dapat membuat config.phpfile ini berisi semua konfigurasi Anda (terpusat dalam satu file, bukan satu untuk JavaScript dan satu untuk PHP). Triknya kemudian adalah memiliki file PHP lain yang echohanya berisi info sisi klien (untuk menghindari menampilkan info yang tidak ingin Anda tampilkan seperti string koneksi database). Sebut saja get_app_info.php:

<?php

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

?>

Di atas dengan asumsi Anda config.phpberisi app_infoparameter:

<?php

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

?>

Jadi info database Anda tetap berada di sisi server, tetapi info aplikasi Anda dapat diakses dari JavaScript Anda, misalnya dengan $http.get('get_app_info.php').then(...);jenis panggilan.

BoDeX
sumber
mengapa menjadikannya sebuah objek?
TheCrazyProfessor
4
Menjadikannya sebagai objek membuat penanganan data menjadi jauh lebih mudah. Ini memungkinkan misalnya untuk mendapatkan semua app_infoparameter ke JavaScript sebagai JSON dengan baris kode minimum.
BoDeX
Objek juga memiliki efek samping diteruskan oleh referensi sejak PHP 5. Ini mungkin hal yang baik atau mungkin tidak. Array diteruskan oleh nilai (tetapi diimplementasikan sebagai COW) jadi mungkin lebih baik menggunakan larik konfigurasi daripada objek config.
Mikko Rantalainen
@ BoDeX saya suka cara ini selalu dan tampaknya menjadi pendekatan yang disukai di sebagian besar artikel, tetapi bagaimana saya mengakses ini melalui kelas? Saya membaca di artikel keamanan bahwa membuat variabel global bukanlah ide yang bagus jadi apa yang Anda sarankan?
Kevlwig
22

Opsi yang saya lihat dengan kelebihan / kelemahan relatif adalah:

Mekanisme berbasis file

Ini mengharuskan kode Anda mencari di lokasi tertentu untuk menemukan file ini. Ini adalah masalah yang sulit dipecahkan dan selalu muncul di aplikasi PHP besar. Namun Anda mungkin perlu menyelesaikan masalah untuk menemukan kode PHP yang dimasukkan / digunakan kembali saat runtime.

Pendekatan umum untuk ini adalah selalu menggunakan direktori relatif, atau mencari dari direktori saat ini ke atas untuk menemukan file yang dinamai secara eksklusif di direktori dasar aplikasi.

Format file yang umum digunakan untuk file konfigurasi adalah kode PHP, file berformat ini, JSON, XML, YAML dan PHP serial

Kode PHP

Ini memberikan sejumlah besar fleksibilitas untuk merepresentasikan struktur data yang berbeda, dan (dengan asumsi itu diproses melalui penyertaan atau memerlukan) kode parsing akan tersedia dari cache opcode - memberikan manfaat kinerja.

The include_path menyediakan sarana untuk abstrak lokasi potensi file tanpa bergantung pada kode tambahan.

Di sisi lain, salah satu alasan utama untuk memisahkan konfigurasi dari kode adalah untuk memisahkan tanggung jawab. Ini menyediakan rute untuk memasukkan kode tambahan ke dalam runtime.

Jika konfigurasi dibuat dari alat, dimungkinkan untuk memvalidasi data dalam alat, tetapi tidak ada fungsi standar untuk melepaskan data untuk disematkan ke kode PHP seperti yang ada untuk HTML, URL, pernyataan MySQL, perintah shell ... .

Data berseri Ini relatif efisien untuk sejumlah kecil konfigurasi (hingga sekitar 200 item) dan memungkinkan penggunaan struktur data PHP apa pun. Diperlukan sedikit kode untuk membuat / mengurai file data (jadi Anda dapat melakukan upaya Anda untuk memastikan bahwa file hanya ditulis dengan otorisasi yang sesuai).

Pelolosan konten yang ditulis ke file ditangani secara otomatis.

Karena Anda dapat membuat serial objek, hal itu menciptakan peluang untuk memanggil kode hanya dengan membaca file konfigurasi (metode ajaib __wakeup).

File terstruktur

Menyimpannya sebagai file INI seperti yang disarankan oleh Marcel atau JSON atau XML juga menyediakan api sederhana untuk memetakan file ke dalam struktur data PHP (dan dengan pengecualian XML, untuk keluar dari data dan membuat file) sambil menghilangkan pemanggilan kode kerentanan menggunakan data PHP serial.

Ini akan memiliki karakteristik kinerja yang mirip dengan data serial.

Penyimpanan database

Ini paling baik dipertimbangkan di mana Anda memiliki sejumlah besar konfigurasi tetapi selektif dalam apa yang diperlukan untuk tugas saat ini - Saya terkejut menemukan bahwa di sekitar 150 item data, lebih cepat untuk mengambil data dari instance MySQL lokal daripada unserialize sebuah datafile.

OTOH ini bukan tempat yang baik untuk menyimpan kredensial yang Anda gunakan untuk terhubung ke database Anda!

Lingkungan eksekusi

Anda dapat menetapkan nilai di lingkungan eksekusi tempat PHP dijalankan.

Ini menghapus persyaratan apa pun agar kode PHP terlihat di tempat tertentu untuk konfigurasi. OTOH tidak menskalakan dengan baik ke sejumlah besar data dan sulit untuk diubah secara universal saat runtime.

Di klien

Satu tempat yang tidak saya sebutkan untuk menyimpan data konfigurasi adalah di klien. Sekali lagi, overhead jaringan berarti bahwa ini tidak berskala dengan baik untuk konfigurasi dalam jumlah besar. Dan karena pengguna akhir memiliki kendali atas data itu harus disimpan dalam format di mana setiap gangguan dapat dideteksi (yaitu dengan tanda tangan kriptografi) dan tidak boleh berisi informasi apa pun yang dikompromikan oleh pengungkapannya (yaitu dienkripsi secara terbalik).

Sebaliknya, ini memiliki banyak manfaat untuk menyimpan informasi sensitif yang dimiliki oleh pengguna akhir - jika Anda tidak menyimpannya di server, informasi tersebut tidak dapat dicuri dari sana.

Direktori Jaringan Tempat lain yang menarik untuk menyimpan informasi konfigurasi di DNS / LDAP. Ini akan bekerja untuk sejumlah kecil informasi kecil - tetapi Anda tidak perlu menggunakan bentuk normal pertama - pertimbangkan, misalnya SPF .

Infrastruktur mendukung caching, replikasi dan distribusi. Oleh karena itu, ini berfungsi dengan baik untuk infrastruktur yang sangat besar.

Sistem Kontrol Versi

Konfigurasi, seperti kode harus dikelola dan versi dikontrol - karenanya mendapatkan konfigurasi langsung dari sistem VC Anda adalah solusi yang layak. Tetapi seringkali hal ini disertai dengan overhead kinerja yang signifikan, karenanya caching mungkin disarankan.

symcbean
sumber
6

Nah - akan agak sulit untuk menyimpan data konfigurasi database Anda dalam database - bukan begitu?

Tapi sungguh, ini adalah pertanyaan yang sangat beralasan karena gaya apa pun benar-benar berfungsi dan itu semua adalah masalah preferensi. Secara pribadi, saya akan memilih variabel konfigurasi daripada konstanta - umumnya karena saya tidak menyukai hal-hal di ruang global kecuali diperlukan. Tidak ada fungsi dalam basis kode saya yang dapat dengan mudah mengakses kata sandi basis data saya (kecuali logika koneksi basis data saya) - jadi saya akan menggunakannya di sana dan kemudian mungkin menghancurkannya.

Sunting : untuk menjawab komentar Anda - tidak ada mekanisme parsing yang akan menjadi yang tercepat (ini, json, dll) - tetapi mereka juga bukan bagian dari aplikasi Anda yang benar-benar perlu Anda fokuskan untuk pengoptimalan karena perbedaan kecepatan akan diabaikan pada file sekecil itu.

Colin M
sumber
2

Define akan membuat konstanta tersedia di mana saja di kelas Anda tanpa perlu menggunakan global, sedangkan variabel memerlukan global di kelas, saya akan menggunakan DEFINE. tetapi sekali lagi, jika parameter db berubah selama eksekusi program, Anda mungkin ingin tetap menggunakan variabel.

phpalix.dll
sumber
apa cara fastet untuk mengeksekusi php? const atau var?
Ali Akbar Azizi
1
@CooPer Mendefinisikan konstanta secara signifikan lebih lambat daripada mendefinisikan variabel. Tetapi menggunakannya sedikit lebih cepat. Karena ini akan digunakan di satu tempat, variabel secara keseluruhan akan menawarkan kinerja yang lebih tinggi.
Colin M
"Significantly" adalah kata yang agak berat untuk itu, jika Anda melihatnya seperti ini, mungkin Anda harus menghubungi php dev guys dan meminta mereka untuk menghapus dukungan konstan!
phpalix
@phpalix Mendefinisikan sebuah konstanta bisa di mana saja 10-20x lebih lambat daripada mendefinisikan variabel dengan nilai yang sama. Menurut saya itu penting. Namun, jika Anda menggunakan banyak konstanta di seluruh aplikasi Anda - itu mungkin terbayar dengan sangat baik. Tetapi membuat konstanta untuk digunakan sekali tidak disarankan.
Colin M
2

Jika Anda berpikir Anda akan menggunakan lebih dari 1 db untuk alasan apa pun, gunakan variabel karena Anda akan dapat mengubah satu parameter untuk beralih ke db yang sama sekali berbeda. Yaitu untuk pengujian, autobackup, dll.

trigun0x2
sumber
2

Anda dapat membuat properti statis penyihir kelas config

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

maka Anda dapat menggunakannya dengan mudah:

Config::$dbHost  

Terkadang dalam proyek saya, saya menggunakan pola desain SINGLETON untuk mengakses data konfigurasi. Sangat nyaman digunakan.

Mengapa?

Misalnya Anda memiliki 2 sumber data dalam proyek Anda. Dan Anda dapat memilih penyihir dari mereka diaktifkan.

  • mysql.dll
  • json

Di suatu tempat di file konfigurasi yang Anda pilih:

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

Saat Anda mengubah seluruh aplikasi sumber harus beralih ke sumber data baru, berfungsi dengan baik dan tidak perlu mengubah kode.

Contoh:

Konfigurasi:

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

Kelas Singleton:

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;
    }
}

... dan di suatu tempat di kode Anda (mis. di beberapa kelas layanan):

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

Kita dapat memperoleh objek AppConfig dari mana saja di sistem dan selalu mendapatkan salinan yang sama (berkat statis). Metode init () kelas disebut In the constructor, yang menjamin hanya satu eksekusi. Init () body memeriksa Nilai config $ dataSource, dan membuat objek baru dari kelas sumber data tertentu. Sekarang skrip kita bisa mendapatkan objek dan mengoperasikannya, bahkan tidak mengetahui implementasi spesifik mana yang sebenarnya ada.

Sebastian Skurnóg
sumber
1

Saya biasanya akhirnya membuat satu file conn.php yang memiliki koneksi database saya. Kemudian saya menyertakan file itu di semua file yang memerlukan kueri database.

Mihir Chhatre
sumber
1
saya tahu itu, tetapi bagaimana Anda menyimpan file basis data Anda, dengan variabel atau const? dan mengapa?
Ali Akbar Azizi
0

Inilah cara saya.

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

?>

Ada keraguan silahkan komentar

Alok Rajasukumaran
sumber
3
Halo! Bisakah Anda memberi contoh penggunaannya? Terima kasih
Nick