Skip to content

Instantly share code, notes, and snippets.

@jaytaph
Created May 10, 2013 14:09
Show Gist options
  • Save jaytaph/5554632 to your computer and use it in GitHub Desktop.
Save jaytaph/5554632 to your computer and use it in GitHub Desktop.
simple php reader/writer
<?php
class MyIni {
protected $file;
protected $section_endings;
protected $keys;
function __construct($filename) {
$this->file = file($filename);
$this->_parse();
}
protected function _parse() {
// Default to global section if no section has been found
$section = "global";
$this->section_endings = array();
$this->keys = array();
foreach ($this->file as $lineno => $line) {
if (preg_match('/\[([^\]]+)\]/', $line, $match)) {
// Found a new section
$section = $match[1];
} else {
// Found a key = val pair
if (preg_match('/^([a-z0-9_.\[\]-]+)\s*=\s*(.*)$/i', $line, $match)) {
$this->keys[$section.".".$match[1]] = array(
// Save offset for this key
'offset' => $lineno,
'value' => $match[2]
);
}
}
// Assume that this line is the last line of a section, skip empty lines though
$line = trim($line);
if (! empty($line)) {
$this->section_endings[$section] = $lineno;
}
}
}
// Check if we match a pattern in our keys
function match($pattern) {
$ret = array();
foreach ($this->keys as $k => $v) {
// Simple filename match is sufficient
if (fnmatch($pattern, $k)) {
$ret[$k] = $v['value'];
}
}
return $ret;
}
// Returns the key part of a string (section.key.with.dots => key.with.dots)
protected function _getKey($key) {
list ($section, $key) = explode(".", $key, 2);
if (! isset($key)) {
$key = $section;
}
return $key;
}
// Returns the section part of a string (section.key => section), or
// "global" when no section has been found.
protected function _getSection($key) {
list ($section, $key) = explode(".", $key, 2);
if (! isset($key)) {
$section = "global";
}
return $section;
}
// Adds - or updates - a key with a new value. Key is formatted like: section.key
function add($key, $val) {
// Build actual line
$line = $this->_getKey($key) . " = " . $val . "\n";
if (isset($this->keys[$key])) {
// Key is present, just change the line
// update in the keys
$this->keys[$key]['value'] = $val;
// update in the file too so both are in sync
$offset = $this->keys[$key]['offset'];
$this->file[$offset] = $line;
} else {
// Key not found. We need to add the key (and possibly the section too)
// Separate the section from the key
$section = $this->_getSection($key);
if (isset($this->section_endings[$section])) {
// Section exists, just add the key to the end of this section
$offset = $this->section_endings[$section] + 1;
} else {
// Section not found, add it to the end of the file
end($this->file);
$offset = key($this->file) + 1;
// Create new section first by adding them
array_splice($this->file, $offset++, 0, "\n");
array_splice($this->file, $offset++, 0, "[".$section."]\n");
}
// Just add the new line
array_splice($this->file, $offset++, 0, $line);
// Reparse everything.
$this->_parse();
print_r($this->keys);
}
}
function remove($key) {
if (isset($this->keys[$key])) {
$offset = $this->keys[$key]['offset'];
unset($this->file[$offset]);
unset($this->keys[$key]);
// Reparse. Needed so our line numbering is correct again
$this->_parse();
}
}
function save($destination) {
$f = fopen($destination, "w");
foreach ($this->file as $lineno => $line) {
fwrite($f, $lineno.": ".$line);
}
fclose($f);
}
}
$ini = new MyIni("/etc/saffire/saffire.ini");
print_r($ini->match("fastcgi.*"));
print_r($ini->match("fastcgi.log.*"));
print_r($ini->match("*socket*"));
print_r($ini->match("*gpg*"));
$ini->remove("gpg.path");
print_r($ini->match("*gpg*"));
$ini->add("gpg.anotherkey", "wootwoot");
print_r($ini->match("*gpg*"));
$ini->add("compile.sign", "false");
$ini->add("fastcgi.listen.backlog", "1234");
$ini->add("repl.ps3", "asfasdfas");
$ini->add("global.test", "ok");
$ini->add("blaat.work", "it");
$ini->add("anohersection.foo", "aa");
$ini->add("anohersection.bar", "yes");
$ini->save("php://stdout");
exit;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment