This article mainly introduces a very perfect PHP configuration class sharing for reading and writing ini format. This article provides class code, use examples, and configuration file examples, for more information about all configurations, see.
/*** Resolution. the configuration file in ini format is a tree-structured object * different sections of the configuration file are inherited by colons * the section used according to hostname is determined by default, if you are not sure, use production * to check the environment first, the remaining sections are checked in the defined order ** @ author ares@phpdr.net **/class Config {/*** resolved configuration file ** @ var stdClass */private $ config; /*** a two-dimensional array, the key is the section * value of the configuration file is an array or callback function * if it is an array, the hostname determines whether to use this section in the array * if it is a callback function, the return value is true or false. to determine whether to use this section ** @ var array */private $ map = arra Y ();/*** section will be parsed, which indicates inheriting '. 'used to differentiate the hierarchical relationship * section '. 'will not be parsed, and the array in the configuration will not be affected. ** @ Param string $ conf * @ throws ErrorException * @ return stdClass */function _ construct ($ conf, $ map) {$ config = $ this-> parseIni (object) parse_ini_string ($ conf, true); if (array_key_exists ('production ', $ map )) {$ production = $ map ['production ']; unset ($ map ['production']); $ map = array_merge (array ('production '=> $ production ), $ map);} else {throw new ErrorException (' Production section not found in config ');} $ section = 'production'; $ hostname = gethostname (); foreach ($ map as $ k => $ v) {if (is_array ($ v) {foreach ($ v as $ v1) {if ($ v1 ==$ hostname) {$ section = $ k; break 2 ;}} elseif (is_callable ($ v) {if (true = call_user_func ($ v) {$ section = $ k; break ;}} else {throw new ErrorException ('wrong map value in '. _ CLASS _) ;}}$ t His-> config = $ config-> $ section;}/*** always returns the configuration object ** @ return mixed */function _ get ($ key) {if (isset ($ this-> config-> $ key) {return $ this-> config-> $ key ;}} /*** split ** @ param stdClass $ v * @ param string $ k1 * @ param mixed $ v1 */private function split ($ v, $ k1, $ v1) {$ keys = explode ('. ', $ k1); $ last = array_pop ($ keys); $ node = $ v; foreach ($ keys as $ v2) {if (! Isset ($ node-> $ v2) {$ node-> $ v2 = new stdClass () ;}$ node = $ node-> $ v2 ;} $ node-> $ last = $ v1; if (count ($ keys)> 0) {unset ($ v-> $ k1 );}} /*** parseIni ** @ param object $ conf * @ return stdClass */private function parseIni ($ conf) {$ confObj = new stdClass (); foreach ($ conf as $ k =>$ v) {// is section if (is_array ($ v) {$ confObj-> $ k = (object) $ v; foreach ($ v as $ k1 => $ v1 ){ Call_user_func (array ($ this, 'Split '), $ confObj-> $ k, $ k1, $ v1) ;}} else {call_user_func (array ($ this, 'split'), $ confObj, $ k, $ v) ;}} unset ($ conf); // process inherited foreach ($ confObj as $ k =>$ v) {if (false! = Strpos ($ k, ':') {if (0 = strpos ($ k, ':') {throw new ErrorException ('config '. $ k. 'is invalid,': 'Can't be the first char ');} elseif (1 <substr_count ($ k ,':')) {throw new ErrorException ('config '. $ k. is invalid, ': 'Can appear only once');} else {$ keys = explode (':', $ k); if (! Isset ($ confObj-> $ keys [1]) {throw new ErrorException ('parent detail '. $ keys [1]. 'doesn' t exist in config file');} else {if (isset ($ confObj-> $ keys [0]) {throw new ErrorException ('config is invalid, '. $ keys [0]. and '. $ k. 'conflicts');} else {$ confObj-> $ keys [0] = $ this-> deepCloneR ($ confObj-> $ keys [1]); $ this-> objectMergeR ($ confObj-> $ keys [0], $ v); unset ($ confObj-> $ k) ;}}} return $ confObj ;} /*** php is a shortest clone by default. the function implements deep clone. ** @ param object $ obj * @ return object $ obj */private function deepCloneR ($ obj) {$ objClone = clone $ obj; foreach ($ objClone as $ k => $ v) {if (is_object ($ v )) {$ objClone-> $ k = $ this-> deepCloneR ($ v) ;}} return $ objClone ;} /*** recursively merge two objects ** @ param unknown $ obj1 * @ param unknown $ obj2 */private function objectMergeR ($ obj1, $ obj2) {foreach ($ obj2 as $ k =>v v) {if (is_object ($ v) & isset ($ obj1-> $ k) & is_object ($ obj1-> $ k) {$ this-> objectMergeR ($ obj1-> $ k, $ v );} else {$ obj1-> $ k = $ v ;}}}}
Easy to use:
$_ENV ['config'] = new Config ( file_get_contents ( __DIR__ . '/config.ini' ), array ( 'development' => array ( 'localhost.localdomain', 'localhost' ), 'production' => array ()) );
Configuration File example:
[product]db.default.dsn="mysql:host=127.0.0.1;dbname=default"db.default.username=rootdb.default.password=123456admin.username=adminadmin.password=123456php.error_reporting=E_ALLphp.display_errors=nophp.log_errors=yesphp.error_log=APP_PATH'/resource/log/phpError.log'php.session.save_path=APP_PATH'/resource/data/session'[development:product]db.test1.dsn="mysql:host=127.0.0.1;dbname=test1"db.test1.username=rootdb.test1.password=123456php.display_errors=yes