PHP Classes

File: class.config_reader.php

Recommend this page to a friend!
  Classes of Keyvan Minoukadeh   Config Manager   class.config_reader.php   Download  
File: class.config_reader.php
Role: ???
Content type: text/plain
Description: Class - config reader
Class: Config Manager
Sorry, no longer supported
Author: By
Last change:
Date: 21 years ago
Size: 11,615 bytes
 

Contents

Class file image Download
<?php /* vim: set ai tabstop=4: */ // $Date: 2002/04/09 01:29:38 $ // $Revision: 1.3 $ // +----------------------------------------------------------------------+ // | CONFIG MANAGER 0.1.2 - 09-Apr-2002 | // +----------------------------------------------------------------------+ // | Author: Keyvan Minoukadeh - keyvan@k1m.com - http://www.k1m.com | // +----------------------------------------------------------------------+ // | PHP class for managing plain text config files. | // +----------------------------------------------------------------------+ // | This program is free software; you can redistribute it and/or | // | modify it under the terms of the GNU General Public License | // | as published by the Free Software Foundation; either version 2 | // | of the License, or (at your option) any later version. | // | | // | This program is distributed in the hope that it will be useful, | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | // | GNU General Public License for more details. | // +----------------------------------------------------------------------+ if (defined('CONFIGMAN_DIR')) { require_once(CONFIGMAN_DIR.'class.config_base.php'); } /** * Config manager reader class * * Use this class to read plain text config files. * This is an extension to the base config class. * * @author Keyvan Minoukadeh <keyvan@k1m.com> * @version 0.1.2 */ class config_reader extends config_base { /** * fetch mode * * CONFIGMAN_FETCH_ASSOC = return config vars as associative array * CONFIGMAN_FETCH_OBJECT = return config vars as an object */ var $fetch_mode = CONFIGMAN_FETCH_ASSOC; /** * allow serialize? */ var $cache_config = false; ///////////// // methods ///////////// /** * Constructor * * @param string $config config file to use * @param int $fetch_mode fetch mode */ function config_reader($config=null, $fetch_mode=null) { // run base constructor if (!is_null($config)) { $this->config_base($config); } if (!is_null($fetch_mode)) { $this->fetch_mode = $fetch_mode; } } /** * Load config * * Parse and update class variables with values found in config. * Cache file refers to a file containing the serialized values found in the config file, * if present it will load the values quicker. * * @param int $fetch_mode either CONFIGMAN_FETCH_ASSOC or CONFIGMAN_FETCH_OBJECT * @param bool $reload if true, will reload values from main config even if cache exists * @return mixed either associative array, or object */ function load($fetch_mode=null, $reload=false) { $func_name = 'load'; clearstatcache(); if (!$this->is_file_valid()) { if ($this->debug) $this->_debug("$func_name: Invalid config file"); } $config = $this->config; $file_cache = $this->config_cache_dir.basename($config).'.cache'; // grab file modification times $config_ts = @filemtime($config); $file_cache_ts = @filemtime($file_cache); // check if cache file available if (!$reload && file_exists($file_cache) && is_readable($file_cache) && ($config_ts == $file_cache_ts)) { if ($this->debug) $this->_debug("$func_name: Loading from cache file"); // unserialize config cache (returns associative array) $fp = fopen($file_cache, 'r'); // shared lock flock($fp, 1); $contents = fread($fp, filesize($file_cache)); // release lock flock($fp, 3); fclose($fp); $config_array = unserialize($contents); if (!is_array($config_array)) { if ($this->debug) $this->_debug("$func_name: Invalid config cache ($file_cache), remove and try again"); return false; } // loop through associative array and update vars foreach ($config_array as $key => $val) { $this->set_param_from_array($key, $val); } } elseif (file_exists($config) && is_readable($config)) { if ($this->debug) $this->_debug("$func_name: Loading from config file"); // parse config file $this->_process_config(file($config)); if ($this->cache_config) { $this->_write_config_cache($file_cache, filemtime($config)); } } else { if ($this->debug) $this->_debug("$func_name: Could not load config file ($config)"); return false; } return $this->_return_config_vars($fetch_mode); } /** * Load config from string * * Same as load() except first parameter will be the string contaning * the config lines. (useful if you're not storing the config in a file, eg. using a DB * or generating it some way) * * @param string $config config contents as string * @param int $fetch_mode either CONFIGMAN_FETCH_ASSOC or CONFIGMAN_FETCH_OBJECT * @return mixed either associative array, or object */ function load_from_string($config, $fetch_mode=null) { $func_name = 'load_from_string'; $config = explode("\n", trim($config)); if (is_array($config) && (count($config) > 0)) { $this->_process_config($config); return $this->_return_config_vars($fetch_mode); } else { if ($this->debug) $this->_debug("$func_name: Invalid config contents"); return false; } } /////////////////////// // PRIVATE FUNCTIONS // /////////////////////// /** * Return config vars * * @param int $fetch_mode CONFIGMAN_FETCH_ASSOC or CONFIGMAN_FETCH_OBJECT or null for default * @return mixed array or object, depending on fetch mode * @access private */ function _return_config_vars($fetch_mode=null) { $return = array(); foreach ($this->param as $key => $val) { $return["$key"] = $val[(string)key($val)]['value']; } if (is_null($fetch_mode)) { $fetch_mode = $this->fetch_mode; } if ($fetch_mode === CONFIGMAN_FETCH_OBJECT) { return (object)$return; } else { return $return; } } /** * Write config cache * * @param string $file_path serialize config array and write to disk * @param int $timestamp unix timestamp to set as modification time * @return bool * @access private * @see load */ function _write_config_cache($file_path, $timestamp=null) { $func_name = '_write_config_cache'; if ($this->cache_config) { $serialized = serialize($this->param); $fp = @fopen($file_path, "w"); if (!$fp) { if ($this->debug) $this->_debug("$func_name: Could not create cache file"); return false; } else { // exclusive lock flock($fp, 2); $result = @fwrite($fp, $serialized); // release lock flock($fp, 3); fclose($fp); if (!$result) { if ($this->debug) $this->_debug("$func_name: Could not write cache file"); return false; } else { if ($this->debug) $this->_debug("$func_name: Cache file written"); // touch file with modification time of main config file (used for comparison) touch($file_path, ((is_null($timestamp) || !$timestamp) ? time() : $timestamp)); @chmod($file_path, 0600); return true; } } } return false; } /** * Process config * * @param array $config each line of the config file as a seperate array element * @return bool true if successfully loaded, false otherwise * @access private */ function _process_config($config) { $func_name = "_process_config"; if (!is_array($config) || (count($config) < 1)) { if ($this->debug) $this->_debug("$func_name: Config file is empty, or is not an array"); return false; } $var = array(); $section = $this->default_section; $comment = ""; $line_count = 0; foreach ($config as $line) { $line_count++; $line = trim($line); if (empty($line)) { continue; } // plain comment if (preg_match('!^'.preg_quote($this->comment).'(.*)$!', $line, $match)) { if (trim($match[1]) != '') { $comment .= trim($match[1])."\n"; } unset($match); continue; } // variable definition if (preg_match('!^'.$this->regex_type.'?('.$this->regex_var.')(\.'.$this->regex_assoc.')?\s*'.preg_quote($this->separator).'\s*(?'.'>(["\'])?)(.*)(?(4)\4)$!i', $line, $match)) { if (trim($match[1]) != '') { $type = $this->type_prefix[$match[1]]; } elseif ($this->default_type != 'auto') { $type = $this->default_type; } elseif ($match[4] == '"' || $match[4] == '\'') { $type = CONFIGMAN_TYPE_STRING; } else { $type = CONFIGMAN_TYPE_INTEGER; } // replace escaped characters (\n \r and \t) if ($match[4] == '"') { $match[5] = preg_replace(array('/(?<!\\\\)\\\\n/','/(?<!\\\\)\\\\r/','/(?<!\\\\)\\\\t/'), array("\n","\r","\t"), $match[5]); $match[5] = str_replace('\\\\', '\\', $match[5]); } $var[$match[2]][][$type] = array( 'value' => $match[5], 'comment' => $comment, 'assoc' => (empty($match[3]) ? null : substr($match[3], 1))); $comment = ""; unset($match); continue; } // section tag (comment) if (preg_match('!^\[('.$this->regex_section.')\]!', $line, $match)) { if (trim($match[1]) != '') { // set previous section vars $this->_set_param_from_config($var, $section); $var = array(); $section = trim($match[1]); } else { $this->_error("Incorrect section tag on line $line_count"); } unset($match); continue; } // unrecognized config syntax if ($this->debug) $this->_debug("$func_name: Unrecognised syntax on line $line_count"); } $this->_set_param_from_config($var, $section); } /** * Set params from parsed config * * Sets parameters for 1 section * * @param array $param parameters for 1 section passed from _process_config * @param string $section section name to enter parameter in * @return bool true * @access private * @see _process_config */ function _set_param_from_config($param, $section) { foreach ($param as $var => $value) { // array? if (count($value) > 1) { // it is an array $cur_val = array(); $cur_comment = ''; // loop through the array foreach ($value as $arr_element) { // grab the type $cur_type = key($arr_element); if (trim($arr_element[$cur_type]['comment']) != '') { if ($cur_comment != '') { $cur_comment .= "------------------------------\n"; } $cur_comment .= $arr_element[$cur_type]['comment']; } // is it associative? if (!is_null($arr_element[$cur_type]['assoc'])) { // store key $cur_key = (string)$arr_element[$cur_type]['assoc']; // add value $cur_val[$cur_key] = $this->_cast_type($arr_element[$cur_type]['value'], $cur_type); } else { // not associative $cur_val[] = $this->_cast_type($arr_element[$cur_type]['value'], $cur_type); } } } else { // not array or single assoc array $cur_type = key($value[0]); $cur_val = $this->_cast_type($value[0][key($value[0])]['value'], $cur_type); $cur_comment = $value[0][key($value[0])]['comment']; $cur_key = $value[0][key($value[0])]['assoc']; if (!is_null($cur_key)) { $cur_val = array("$cur_key" => $cur_val); } } $this->set_param($var, $cur_val, $cur_comment, $section); } return true; } } ?>