Ini-Dateien Lesen und Schreiben
Ini file handling class
Sometimes old-fashioned ini-files have to be read or written. This class is a possible interface for these tasks. I use it because I have to convert files sometimes - with case sensitive keys.
Manchmal müssen altertümliche ini-Dateien gelesen oder geschrieben werden. Eine Möglichkeit hierfür bietet diese Klasse. Ich benutze sie vor allem wenn ich Konfigurationen in einem Schritt in ein Datensatz einlesen möchte.
Sample source code
Anwendungsbeispiel
<?php
require_once('swlib/swlib.class.php');
use sw\IniFile;
use sw\FileSystem;
// Path to a temporary config file
$path = FileSystem::getTempDirectory() . '/test_configfile.ini';
print "Config file pPath = '$path'\n\n";
FileSystem::writeFile($path, <<<HERE_CONFIG
[section 1]
key1.1=1000
key1.2=A text
[section 2]
key2.1=2000
key2.2=A second text
HERE_CONFIG
);
// Instantiate ...
$cfg = new IniFile($path);
print "\$cfg->data = " . print_r($cfg->data, true) . "\n";
// Modify data ...
$cfg->data['section 3'] = array(
'key3.1' => 2000,
'key3.2' => 'A third text'
);
// Save the file
$cfg->save();
print "New content = " . FileSystem::readFile($path) . "\n\n";
unlink($path);
Output
Ausgabe
Config file pPath = '/tmp/test_configfile.ini'
$cfg->data = Array
(
[section 1] => Array
(
[key1.1] => 1000
[key1.2] => A text
)
[section 2] => Array
(
[key2.1] => 2000
[key2.2] => A second text
)
)
New content =
[section 1]
key1.1=1000
key1.2=A text
[section 2]
key2.1=2000
key2.2=A second text
[section 3]
key3.1=2000
key3.2=A third text
Class source code
Note that only the data are saved, comments are not read or saved. The entries and sections are case sensitive.
Klassen-Quelltext
Beachte, dass nur die Daten gespeichert werden, keine Kommentare. Einträge und Sections sind case-sensive.
<?php
/**
* Initialisation file access. Load/save availability. Sections and
* keys are accessable using the public data array.
* @gpackage de.atwillys.sw.php.swLib
* @author Stefan Wilhelm
* @copyright Stefan Wilhelm, 2008-2010
* @license GPL
* @version 1.0
*/
namespace sw;
class IniFile {
/**
* The complete path to the initialisation file
* @var string
*/
private $file = '';
/**
* Stores the data in an assoc. array in form
* $config->data['section']['key']
* @var array
*/
public $data = array();
/**
* Constructor. If a file specified with the $path argument
* exists, then the file is directly read and parsed.
* Throws no exception if the file does not exist. Instead,
* the path is saged in the $file instance variable for later
* saving.
* @param string $path
*/
public function __construct($path=null) {
$this->file = $path;
if (is_file($path)) {
// Readfile throws exceptions
$contents = explode("\n", str_replace("\r", "\n", FileSystem::readFile($path)));
$this->data = array();
$actualSection = null;
foreach ($contents as $line) {
$line = ltrim($line, " \t\v");
// Check comments
if (empty($line)) {
continue;
} else {
switch (substr($line, 0, 1)) {
case '*':
case '#':
case "'":
continue;
break;
case '[':
$line = trim($line, " \t\v[]");
if (!isset($this->data[$line])) {
$this->data[$line] = array();
}
$actualSection = &$this->data[$line];
break;
default:
$line = explode('=', $line, 2);
$line[0] = trim($line[0], " \t");
$actualSection[$line[0]] = isset($line[1]) ? $line[1] : '';
$actualKey = &$actualSection[$line[0]];
}
}
}
}
}
/**
* Returns a new ConfigFile instance containing the loaded and parsed
* data. Throws an exception if the file does not exist.
* @param string $path
*/
public static function load($path) {
$o = new self($path);
if (!is_file($path)) {
// The constructor loads a file of it exists in the file system
// The load method must throw an exception if the file does not exist
throw new LException("Config file to load does not exist: ':path'", array(':path' => $path));
}
}
/**
* Saves the content of the assoc. data array in the file specified by
* $path, or by the already set $file instance variable. Note that comments
* will be removed.
* @param string $path
*/
public function save($path=null) {
if (!is_array($this->data)) {
throw new LException('Config file data must be an array of arrays (sections of key-value-pairs)');
} else {
$r = '';
foreach ($this->data as $section => $pairs) {
if (is_array($pairs)) {
$section = trim($section);
$r .= "[$section]\n";
foreach ($pairs as $key => $value) {
if (!settype($value, 'string')) {
throw new LException("There must be a string representation of the value of a config entry (value of [:section][:key] )", array(':section' => $section, ':key' => $key));
} else {
$r .= trim($key) . '=' . str_replace("\r", '', str_replace("\n", '', $value)) . "\n";
}
}
} else {
throw new LException('A config file section must be an assoc. array (pattern is $data[section][key]=value');
}
}
$path = trim($path);
if (strlen($path) == 0) {
$path = $this->file;
}
// Will throw an exception if something's wrong
FileSystem::writeFile($path, $r);
}
}
}