bonjour
suite au développement d'une classe de gestion des licences pour mes différents projets, je me suis retrouvé en train d’écrire ce code afin de récupérer les infos nécessaires à la validation à distance des licences attribués à chaque client.
cette classe permet non seulement de lire un fichier de configuration, mais aussi d'y écrire (ou modifier une valeur) sans écraser celle déjà existantes.
à l'ajout d'un élément dont la section n'est pas indiquée, il placée sous une section "root"(elle est créée si elle n'existe pas encore) et la relecture de cet élément reste transparente pour l'utilisateur:
class initool{
private $inifile='./config.ini';
private $datas = array();
const sep = ':';
const ds = DIRECTORY_SEPARATOR;
public function __construct($file)
{
if(!empty($file)) $this->inifile = $file;
$ext=strtolower(pathinfo($this->inifile, PATHINFO_EXTENSION));
$filename=pathinfo($this->inifile, PATHINFO_FILENAME);
$dir = rtrim(pathinfo($this->inifile, PATHINFO_DIRNAME),ds);
if($ext !=='ini') $this->inifile = $dir.ds.$filename.'.ini';
if(!file_exists($this->inifile)) touch($this->inifile);
$this->datas=$this->parse($this->inifile);
}
public function get($section=null, $item=null)
{
if($item) $item = trim(strtolower($item));
if($section) $section = trim(strtolower($section));
if(!count($this->datas)) return false;
if(func_num_args() == 0) return $this->datas;
if((!$item and $section) or ($item and !$section))
{
if(!$item) $item = $section;
if(!isset($this->datas$item]))
{
if(isset($this->datas'root']$item])) return $this->datas'root']$item];
return false;
}
return $this->datas$item];
}
if(!isset($this->datas$section]$item])) return false;
return $this->datas$section]$item];
}
public function set($section=null,$item,$value=null)
{
$numarg = func_num_args();
$arg=func_get_args();
switch($numarg)
{
case 1:
if(!is_array($arg[0])) return false;
$item=array_change_key_case($arg[0], CASE_LOWER);
$section=null;
$value=null;
break;
case 2:
if(is_array($arg[0])) return false;
$_arg = strtolower(trim($arg[0]));
if(is_array($arg[1]))
{
$section=$_arg; $item =array_change_key_case($arg[1], CASE_LOWER);$value=null;
}
else
{$item = $_arg;$value=$arg[1];$section=null;}
break;
default:
break;
}
$section = $section? trim(strtolower($section)) : 'root';
if(!is_array($item))
{
if(!$value) return false;
$item=trim(strtolower($item));
if(!isset($this->datas$section]$item]) or !is_array($this->datas$section]$item])):
$this->datas$section]$item]=$value;
else:
if(!is_array($value)) $value = array($value);
$this->datas$section]$item] = array_merge($this->datas$section]$item],$value);
endif;
}
else
{
if($value) return false;
$sectionsize=count($this->datas$section]);
$itemsize = count($item);
if($sectionsize)
{
if($itemsize=='1')
{
if(isset($this->datas$section][key($item)]))
$this->datas$section][key($item)] = array_merge($this->datas$section][key($item)],$item[key($item)]);
else if(!is_numeric(key($item))) $this->datas$section][key($item)]=$item[key($item)];
}
else $this->datas$section] = array_merge($this->datas$section],$item);
}
else $this->datas$section] = $item;
}
$this->save();
}
public function del($section, $item=null)
{
$section = trim(strtolower($section));
if($item) $item = trim(strtolower($item));
if(!$item or !strlen($item))
{
$item = $section;
if(!isset($this->datas$item]))
{
if(isset($this->datas'root']$item])) unset($this->datas'root']$item]);
}
else unset($this->datas$item]);
}
else
{
$sectionsize=count($this->datas$section]);
if($sectionsize >'1')
if(isset($this->datas$section]$item])) unset($this->datas$section]$item]);
else
if(isset($this->datas$section]$item])) unset($this->datas$section]);
}
$this->save();
}
/**
*
* @param string $inifile
* @return array
*/
private function parse($inifile)
{
$inidatas = parse_ini_file($inifile, true);
$output = array();
foreach($inidatas as $namespace => $properties)
{
list($name, $extends) = explode(sep, $namespace);
$name = trim($name);
$extends = trim($extends);
// create namespace if necessary
if(!isset($output$name])) $output$name] = array();
// inherit base namespace
if(isset($inidatas$extends]))
{
foreach($inidatas$extends] as $prop => $val)
$output$name]$prop] = $val;
}
// overwrite / set current namespace values
foreach($properties as $prop => $val)
$output$name]$prop] = $val;
}
return $output;
}
/**
* @transform an array of datas into the ini file datas format.
* @param array $datas
* @return string
*/
private function prepare($datas=array())
{
$data='';
foreach($datas as $section => $groupe)
{
if(!is_array($groupe)) $data .= $section.'='.(is_numeric($groupe) ? $groupe : '"'.$groupe.'"').PHP_EOL;
else
{
$data.=''.$section.']'.PHP_EOL; // \n est une entrée à la ligne
$data.= $this->prepare($groupe);
}
}
return $data;
}
private function save()
{
$content = $this->prepare($this->datas);
if(false===file_put_contents($this->inifile,$content,LOCK_EX))
throw new Exception('Impossible d\'écrire dans ce fichier');
}
/* fin de la classe*/
}
son utilisation est simple:
/*provenant du formulaire*/
$licence = array(
'software'=> 'Iriven MVC System', // Application Name,
'version'=> 1.04, // Application Version
'copyright'=> '© Iriven France', // you can limit the key to per domain
'username'=> 'mon client', // you can limit the key to per user name or compagny
'uniqid'=> 1025, // add if any (user id)
'domain'=> 'monclient.com', // you can limit the key to per domain
'expiration'=> '1390389563', // [time()+(30*24*3600)]; (30 days) you can limit the key to per expiration time
'algorithm'=>'md5',
'serial'=>'736CC-AFB84-9B6C0-65252-6C107',//by key generator
'salt'=>pack('H*', md5(time())),
'lastvalidation' => 98745612 // default: time(), execution du script pour la 1ere fois
);
$ini = new initool('./licence.ini');
$ini->set('licence',$licence); //with section
$test = array('test1'=>'my tester1','test2'=>'my tester2','test3'=>'my tester3');
$ini->set($test); //no section
$ini->set('repo','centos'); //no section
$ini->set('linux','repo','fedora'); //with section
echo $ini->get('test1').PHP_EOL;
echo $ini->get('test2').PHP_EOL;
echo $ini->get('test3').PHP_EOL;
echo '<pre>';
print_r($ini->get('licence'));
echo '</pre>';
echo '<pre>';
print_r($ini->get());
echo '</pre>';
rapport de bug et mise à jour, suivez moi ici:
https://github.com/iriven/initool
nouvelle version disponible avec une prise en charge de nouveax formats de fichiers.
la classe a donc ete renommée en IrivenConfigManager (car ne gere plus uniquement les fichiers .ini)
ajout de la methode "del" permettant de supprimer une entrée, du fichier de configuration