ConfigEditor README
===================
CONTENTS
===================
1. Overview
2. Usage
3. License
4. Feedback
1. Overview
===================
When writing a large web-application, which is supposed to withstand an enormous traffic, the speed of each detail is quite essential. Even the application's configuration must be loaded/parsed as quick as possible. And the best solution for that is to put the config into includable PHP-script, for example:
<?php
// config value 1
$cfg_value1 = 10;
// config value 2
$cfg_value2 = '/home';
...
?>
That is really fast, and most of the work is done here:
a) we do not have to parse the config file -- it is done by PHP
b) as it is a PHP code, it may be cached by some cache extensions (such as APC)
But everything is fine while our application is for our personal use: we can always edit the config as we like it. But situation changes when the application is to be operated by someone not knowing PHP syntax, or at least having no opportunity to modify the config "by hands".
Any enterprise-level web-application has something like admin section, where the user is able to change application settings. The user obviosly does not (should not) know how the configuration is saved.
And that is where ConfigEditor class may come to help.
ConfigEditor class is used to generate/edit config files which are includable PHP-scripts.
2. Usage
===================
a) Initializing
The usage of the class is quite simple. First of all we create an instance. The constructor has no arguents.
$config = new ConfigEditor();
If you already have a config, you may load it into the instance in such way:
$config->LoadFromFile($path_to_config);
In some cases you may want to read the config file yourself, and ask ConfigEditor to parse the string, for example:
$config_source = file_get_contents($path_to_config);
$config->LoadFromStr($config_source);
b) Adding/modifying existing variables
Lets try to add those two variables (from Overview section). The code may look like this:
$config->SetVar('cfg_value1', 10, 'config value 1');
$config->SetVar('cfg_value2', '/home', 'config value 2');
Note that ConfigEditor::SetVar method is used both for adding new variables and editting existsing ones.
You can alose add more complex types, such as arrays:
$winners = array('Ivan', 'Alexandr', 'Mihail');
$config->SetVar('cfg_winners', $winners); // Comments are optional
c) Getting variables from config
See the code below:
echo '<table>';
$vars = $config->GetVarNames();
foreach ($vars as $var_name) {
$var = $config->GetVar($var_name);
echo '<tr><td>'.htmlspecialchars($var[CE_VARNAME]).'</td>';
echo '<td>'.htmlspecialchars(print_r($var[CE_VARVALUE], true)).'</td>';
echo '<td>'.htmlspecialchars($var[CE_VARCOMMENT]).'</td></tr>';
}
echo '</table>';
ConfigEditor::GetVarNames does what is says: it retunrs an array containing all variable names currently held by the ConfigEditor instance. After that we foreach the array and get additional info about each var:
$var = $config->GetVar($var_name);
$var now is na array of the following structure:
$var[CE_VARNAME] - holds variable name
$var[CE_VARVALUE] - holds the value
$var[CE_VARCOMMENT] - holds the comment associated with the variable
d) Removing variables from
To remove the variable from config we should call $config->DeleteVar($var_name), where $var_name is the name of variable to be deleted.
e) Rendering config file
To render the config, you should use ConfigEditor::Save() function.
$config_source = $config->Save();
$config_source will now contain the PHP-code like this:
<?php
// config value 1
$cfg_value1 = 10;
// config value 2
$cfg_value2 = '/home';
$cfg_winners = array (
0 => 'Ivan',
1 => 'Alexandr',
2 => 'Mihail',
);
?>
ConfigEditor may also automatically save the source to the specified file. You should only pass the file name as the argument to Save():
$config->Save($path_to_config);
But this way is not recommended: Save() always returns PHP-code; if the file operation fails - you will not know it.
f) RAW values
Though config files are includable, they should not contain any "executable" code: any config file in my understanding should be a "colletion" of KEY = VALUE pairs, without any initialization instructions or smth like that.
But on the other hand, it is sometimes useful to have values which are evaluated somehow when the config is included.
Assume that I have a ROOTDIR constant defined in my main script (which includes the config):
define('ROOTDIR', dirname(__FILE__));
Assume also that I have a config variable like:
$cfg_cachedir = ROOTDIR.'/cache';
When I include the config, $cfg_cachedir is evaluated into 'D:/some/path/cache' for example.
But what will happen, if I try to add such var as we did before:
$config->SetVar('cfg_cachedir', "ROOTDIR.'/cache'");
The result is not that I expect to have:
$cfg_cachedir = 'ROOTDIR.\'/cache\'';
As you may have guessed, ConfigEditor uses var_export on the values before putting them into the config. Thats why my cfg_cachedir is rendered in such way. To tell ConfigEditor that a value should not be var_export'ed (that a value is RAW value), you should pass 4th argument (true) to SetVar:
$config->SetVar('cfg_cachedir', "ROOTDIR.'/cache'", '', true);
ConfigEditor will put the "ROOTDIR.'/cache'" untouched. The result will be correct:
$cfg_cachedir = ROOTDIR.'/cache';
Also, ConfigEditor checks the raw value to be syntatically correct. If it is not, Exception will be thrwon by SetVar.
g) Misc
Comments passed as a 3rd argument to SetVar may be of any length and even multiline. ConfigEditor automatically wordwraps the comment using CE_WORDWRAP constant value as a line length (40 by default). You may define that constant in your script prior to including ConfigEditor class file (confedit.class.php):
define('CE_WORDWRAP', 70);
require_once('confedit.class.php');
When rendering config (and also when wordwrapping comments), ConfigEditor uses CE_NEWLINE constant as a new-line sequence ("\n" by default). You can also define that constant ("\r\n" for example) prior to including ConfigEditor class.
define('CE_NEWLINE', "\r\n");
3. License
===================
Copyright (c) 2008, Alexandr Egorov
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4. Feedback
===================
My email is amego2006@gmail.com |