PHP'de bir yapılandırma dosyası oluşturma


104

PHP projem için bir yapılandırma dosyası oluşturmak istiyorum, ancak bunu yapmanın en iyi yolunun ne olduğundan emin değilim.

Şu ana kadar 3 fikrim var.

1-Kullanım Değişkeni

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

2-Sabit Kullan

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

3-Veritabanı Kullanın

Yapılandırmayı sınıflarda kullanacağım, bu yüzden hangi yolun en iyi veya daha iyi bir yolu olacağından emin değilim.


12
4) Bir ini dosyası kullanın. 5) Bir YAML dosyası kullanın. 6) Bir JSON dosyası kullanın. 7) ... Çok fazla yol var ... En azından yargılamak için bazı kriterler tanımlayın, genel olarak "en iyi" diye bir şey yoktur.
deceze

@deceze oruçlu yol nedir? (hafıza ve hızlı)
Ali Ekber Azizi

O halde bu sizin için ilginç bir okuma olmalı: stackoverflow.com/questions/823352/…
2013

1
Laravel'in yaptığı gibi kullanıyorum (yani Laravel'i kullanmadığım zaman). Ana bilgisayar adına bağlı olarak belirli bir yapılandırma dosyası yükleyen bir sınıf oluşturuyorum. Sonra onu kullanarak çağırırım Config::get('key');. pastebin.com/4iTnjEuM
MisterBla

Yanıtlar:


224

Basit ama zarif bir yol, config.phpyalnızca bir dizi döndüren bir dosya (veya ona ne derseniz deyin) oluşturmaktır:

<?php

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

Ve sonra:

$configs = include('config.php');

10
Bu yöntemi de seviyorum - bence dahil edilen bir dosyada bir değişkeni bildirmekten ve betiğinizde olacağını varsaymaktan daha temiz
Colin M

Yapılandırma dosyası oluşturmanın bu yanıt yönteminin neresinde? Benim gibi php acemi için?
Luka

@Luka var_export fonksiyonunu kullanabilirsiniz .
Hasan Bayat

78

INI dosyası kullanmak esnek ve güçlü bir çözümdür! PHP'nin düzgün bir şekilde işlemek için yerel bir işlevi vardır . Örneğin, şu şekilde bir INI dosyası oluşturmak mümkündür:

app.ini

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

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

Yani yapmanız gereken tek şey aramak:

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

Ardından $inidiziyi kullanarak tanımlara kolayca erişebilirsiniz .

echo $ini['db_name'];     // mydatabase
echo $ini['db_user'];     // myuser
echo $ini['db_password']; // mypassword
echo $ini['app_email'];   // mailer@myapp.com

ÖNEMLİ: Güvenlik nedenleriyle INI dosyası ortak olmayan bir klasörde olmalıdır


Bunu kullanmak da güvenli mi? Bir kullanıcı ini dosyasının yolunu tahmin ederse ve tarayıcısında oraya giderse, dosyada ne olduğunu görür mü?
NickGames

1
@NickGames, aksi takdirde ciddi bir güvenlik riski altında olacak, olmayan bir ortak klasör içinde dosya koyması gerekir
Marcio Mazzucato

2
@NickGames, lütfen Docs of parse_ini_file ()
R Picheta

20
Bu yaklaşımı beğendim. Bonus ipucu: Dosyayı app.ini.php olarak yeniden adlandırın. Ardından ilk satıra ekleyin ;<?php die(); ?>. Bu dosyanın yanlışlıkla ortak bir klasörde görünmesi durumunda, PHP dosyası olarak değerlendirilecek ve ilk satırda ölecektir. Dosya ile parse_ini_fileokunursa, ilk satırı ;.
andreas

1
Not: ini dosyasındaki bir değer alfanümerik olmayan karakterler içeriyorsa , çift ​​tırnak ( ") içine alınması gerekir . Örneğin, herhangi bir şifre alfanümerik olmayan karakterler içerir.
Key Shang

25

@Hugo_leonardo'nun çözümünün ufak bir evrimini kullanıyorum :

<?php

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

?>

Bu, $configs->hostyerine php: eklediğinizde nesne sözdizimini kullanmanıza izin verir $configs['host'].

Ayrıca, uygulamanız istemci tarafında ihtiyaç duyduğunuz yapılandırmalara sahipse (bir Angular uygulaması gibi), bu config.phpdosyanın tüm yapılandırmalarınızı içermesini sağlayabilirsiniz (JavaScript için bir ve PHP için bir dosya yerine tek bir dosyada merkezileştirilmiş). İşin püf noktası, echoyalnızca istemci tarafı bilgisini içeren başka bir PHP dosyasına sahip olmaktır (veritabanı bağlantı dizesi gibi göstermek istemediğiniz bilgileri göstermekten kaçınmak için). Ara söyle get_app_info.php:

<?php

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

?>

Yukarıdakilerin config.phpbir app_infoparametre içerdiğini varsayarsak :

<?php

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

?>

Böylece veritabanınızın bilgileri sunucu tarafında kalır, ancak uygulama bilgilerinize JavaScript'inizden, örneğin bir $http.get('get_app_info.php').then(...);arama türü ile erişilebilir .


neden bir nesne yapalım?
TheCrazyProfessor

4
Bunu bir nesne yapmak, verilerin işlenmesini çok daha kolay hale getirir. Örneğin app_info, minimum kod satırıyla tüm parametreleri JavaScript'e JSON olarak almayı sağlar .
BoDeX

Nesnelerin ayrıca PHP 5'ten beri referans olarak aktarılmanın bir yan etkisi vardır. İyi bir şey olabilir veya olmayabilir. Diziler değere göre aktarılır (ancak COW olarak uygulanır), bu nedenle yapılandırma nesneleri yerine yapılandırma dizilerini kullanmak daha iyi olabilir.
Mikko Rantalainen

@BoDeX bu yolu her zaman seviyorum ve çoğu makalede tercih edilen yaklaşım gibi görünüyor, ancak buna sınıf aracılığıyla nasıl erişebilirim? Güvenlik makalesinde global değişkenler oluşturmanın iyi bir fikir olmadığını okudum, peki ne önerirsiniz?
Kevlwig

22

Göreceli yarar / zayıflıklarla gördüğüm seçenekler şunlardır:

Dosya tabanlı mekanizmalar

Bunlar, ini dosyasını bulmak için kodunuzun belirli konumlara bakmasını gerektirir. Bu, çözülmesi zor bir sorundur ve büyük PHP uygulamalarında her zaman ortaya çıkan bir sorundur. Bununla birlikte, çalışma zamanında eklenen / yeniden kullanılan PHP kodunu bulmak için muhtemelen sorunu çözmeniz gerekecektir.

Buna genel yaklaşımlar, her zaman göreceli dizinleri kullanmak veya uygulamanın temel dizininde özel olarak adlandırılmış bir dosya bulmak için geçerli dizinden yukarı doğru arama yapmaktır.

Yapılandırma dosyaları için kullanılan yaygın dosya biçimleri PHP kodu, ini biçimli dosyalar, JSON, XML, YAML ve serileştirilmiş PHP'dir

PHP kodu

Bu, farklı veri yapılarını temsil etmek için büyük miktarda esneklik sağlar ve (dahil etme veya gerektirme yoluyla işlendiğini varsayarsak) ayrıştırılan kod, işlem kodu önbelleğinden kullanılabilir - performans avantajı sağlar.

İnclude_pathınız ek kod dayanmadan dosyanın potansiyel yerleri soyutlayarak için bir araç sağlar.

Öte yandan, yapılandırmayı koddan ayırmanın ana nedenlerinden biri sorumlulukları ayırmaktır. Çalışma zamanına ek kod eklemek için bir yol sağlar.

Konfigürasyon bir araçtan oluşturulmuşsa, araçtaki verileri doğrulamak mümkün olabilir, ancak HTML, URL'ler, MySQL ifadeleri, kabuk komutları için olduğu gibi PHP koduna gömmek için veriden çıkış yapmak için standart bir işlev yoktur ... .

Serileştirilmiş veri Bu, küçük miktarlarda yapılandırma (yaklaşık 200 öğeye kadar) için nispeten etkilidir ve herhangi bir PHP veri yapısının kullanımına izin verir. Veri dosyasını oluşturmak / ayrıştırmak için çok az kod gerektirir (böylece çabalarınızı dosyanın yalnızca uygun yetkilendirme ile yazılmasını sağlamak için harcayabilirsiniz).

Dosyaya yazılan içeriğin kaçması otomatik olarak yapılır.

Nesneleri serileştirebildiğiniz için, sadece yapılandırma dosyasını (__wakeup sihirli yöntemi) okuyarak kodu çağırmak için bir fırsat yaratır.

Yapılandırılmış dosya

Marcel veya JSON veya XML tarafından önerildiği gibi bir INI dosyası olarak saklamak, aynı zamanda dosyayı bir PHP veri yapısına eşlemek için basit bir api sağlar (ve XML dışında, verilerden kaçmak ve dosyayı oluşturmak için) kod çağrısını ortadan kaldırır. serileştirilmiş PHP verilerini kullanan güvenlik açığı.

Serileştirilmiş verilere benzer performans özelliklerine sahip olacaktır.

Veritabanı depolama

Bu, en iyi şekilde, büyük miktarda yapılandırmanız olduğunda, ancak mevcut görev için neyin gerekli olduğu konusunda seçici olduğunuzda dikkate alınır - yaklaşık 150 veri öğesinde, verileri yerel bir MySQL örneğinden almanın verilere göre daha hızlı olduğunu görünce şaşırdım. bir veri dosyasını seri hale getirmeyin.

OTOH, veritabanınıza bağlanmak için kullandığınız kimlik bilgilerini saklamak için iyi bir yer değildir!

Yürütme ortamı

Değerleri PHP'nin içinde çalıştığı yürütme ortamında ayarlayabilirsiniz .

Bu, PHP kodunun yapılandırma için belirli bir yere bakma gereksinimini ortadan kaldırır. OTOH, büyük miktarda veriye iyi ölçeklenmez ve çalışma zamanında evrensel olarak değiştirilmesi zordur.

Müşteride

Yapılandırma verilerini depolamak için bahsetmediğim bir yer, istemcidir. Yine ağ ek yükü, bunun büyük miktarda konfigürasyona iyi ölçeklenmediği anlamına gelir. Ve son kullanıcı veriler üzerinde kontrole sahip olduğu için, herhangi bir tahrifatın tespit edilebildiği bir formatta saklanmalıdır (yani bir kriptografik imza ile) ve ifşası nedeniyle tehlikeye giren herhangi bir bilgi içermemelidir (yani tersine çevrilebilir şekilde şifrelenmiş).

Tersine, son kullanıcının sahip olduğu hassas bilgileri depolamak için bunun birçok yararı vardır - eğer bunu sunucuda saklamıyorsanız, oradan çalınamaz.

Ağ Dizinleri Yapılandırma bilgilerini depolamak için bir başka ilginç yer de DNS / LDAP'dir. Bu, az sayıda küçük bilgi için işe yarar - ancak 1. normal biçime bağlı kalmanıza gerek yoktur - örneğin SPF'yi düşünün .

Altyapı, önbelleğe alma, çoğaltma ve dağıtımı destekler. Bu nedenle çok büyük altyapılar için iyi çalışıyor.

Sürüm Kontrol sistemleri

Kod gibi yapılandırma da yönetilmeli ve sürüm kontrollü olmalıdır - bu nedenle yapılandırmayı doğrudan VC sisteminizden almak uygun bir çözümdür. Ancak genellikle bu, önemli bir performans yükü ile birlikte gelir, bu nedenle önbelleğe alma tavsiye edilebilir.


6

Veritabanı yapılandırma verilerinizi bir veritabanında saklamak biraz zor olurdu - sence de öyle değil mi?

Ama gerçekten, bu oldukça fazla düşünülmüş bir soru çünkü herhangi bir stil gerçekten işe yarıyor ve hepsi bir tercih meselesi. Kişisel olarak, sabitler yerine bir konfigürasyon değişkenini tercih ederim - çünkü genellikle gerekli olmadıkça global alandaki şeyleri sevmem. Kod tabanımdaki işlevlerin hiçbiri veritabanı parolama (veritabanı bağlantı mantığım dışında) kolayca erişememeli - bu yüzden onu orada kullanır ve sonra muhtemelen yok ederdim.

Düzenleme : yorumunuzu yanıtlamak için - ayrıştırma mekanizmalarının hiçbiri en hızlı (ini, json, vb.) Olmaz - ancak bunlar, uygulamanızın hız farkı nedeniyle gerçekten optimize etmeye odaklanmanız gereken parçaları da değildir. bu kadar küçük dosyalarda ihmal edilebilir.


2

Define, değişkeni sınıfta global kullanmaya gerek kalmadan sınıfınızın her yerinde kullanılabilir hale getirecek, ben de DEFINE kullanacağım. ama yine de, program yürütülürken db parametreleri değişirse, değişkene bağlı kalmak isteyebilirsiniz.


php'yi çalıştırmanın fastet yolu nedir? const veya var?
Ali Ekber Azizi

1
@CooPer Sabitleri tanımlamak, değişkenleri tanımlamaktan önemli ölçüde daha yavaştır. Ancak bunları kullanmak biraz daha hızlıdır. Bunlar tek bir yerde kullanılacağından, değişkenler genel olarak daha yüksek performans sunacaktır.
Colin M

"Önemli ölçüde" bunun için biraz ağır bir kelime, eğer bu şekilde bakıyorsanız, belki php geliştiricileriyle iletişime geçmeli ve onlardan sürekli desteği kaldırmalarını istemelisiniz!
phpalix

@phpalix Bir sabitin tanımlanması, aynı değere sahip bir değişkeni tanımlamaktan 10-20 kat daha yavaş olabilir. Bunun önemli olduğunu söyleyebilirim. Bununla birlikte, sabiti uygulamanız boyunca yoğun bir şekilde kullanırsanız - çok iyi karşılığını verebilir. Ancak bir kez kullanmak için bir sabit oluşturmak tavsiye edilmez.
Colin M

2

Herhangi bir nedenle 1 db'den fazlasını kullanacağınızı düşünüyorsanız, değişkenle gidin çünkü tamamen farklı bir db'ye geçmek için bir parametreyi değiştirebileceksiniz. Yani test, otomatik yedekleme vb.


2

Bir yapılandırma sınıfı cadı statik özellikleri oluşturabilirsiniz

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

o zaman basitçe kullanabilirsiniz:

Config::$dbHost  

Bazen projelerimde konfigürasyon verilerine erişmek için SINGLETON bir tasarım modeli kullanıyorum. Kullanımda çok rahat.

Neden?

Örneğin projenizde 2 veri kaynağınız var. Ve bunlardan cadı seçebilirsiniz etkinleştirildi.

  • mysql
  • json

Yapılandırma dosyasında seçtiğiniz bir yer:

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

Kaynağı tüm uygulama shoud anahtarını yeni veri kaynağına değiştirdiğinizde, iyi çalışın ve kodda değişiklik yapmanız gerekmez.

Misal:

Yapılandırma:

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

Singleton sınıfı:

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

... ve kodunuzun herhangi bir yerinde (örneğin, bazı hizmet sınıflarında):

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

Sistemin herhangi bir yerinden bir AppConfig nesnesi elde edebilir ve her zaman aynı kopyayı alabiliriz (statik sayesinde). Sınıfın init () yöntemi, yalnızca bir yürütmeyi garanti eden Yapıcıda olarak adlandırılır. Init () body, $ dataSource config değerini denetler ve belirli veri kaynağı sınıfının yeni nesnesini oluşturur. Artık betiğimiz, hangi özel uygulamanın gerçekten var olduğunu bile bilmeden nesneyi alıp üzerinde çalışabilir.


1

Normalde veritabanı bağlantılarımı içeren tek bir conn.php dosyası oluşturuyorum. Ardından bu dosyayı veritabanı sorguları gerektiren tüm dosyalara ekliyorum.


1
Bunu biliyorum, ancak veri tabanı dosyanızı değişken veya sabit ile nasıl kaydedersiniz? ve neden?
Ali Ekber Azizi

0

İşte benim yolum.

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

?>

Herhangi bir şüpheniz varsa lütfen yorum yapın


3
Merhaba! Kullanımın bir örneğini verebilir misiniz? Teşekkürler
Nick
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.