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>';

3 réponses


iriven
Auteur
Réponse acceptée

rapport de bug et mise à jour, suivez moi ici:
https://github.com/iriven/initool

iriven
Auteur
Réponse acceptée

nouvelle version disponible avec une prise en charge de nouveax formats de fichiers.

  • php-Array (type composer)
  • json

la classe a donc ete renommée en IrivenConfigManager (car ne gere plus uniquement les fichiers .ini)

https://github.com/iriven/IrivenConfigManager

iriven
Auteur

ajout de la methode "del" permettant de supprimer une entrée, du fichier de configuration