среда, 10 июля 2013 г.

Зарузчик конфигов (PHP)

Удобная штука получилась...


<?php  
 class Config  
 {  
   const AUTO = 'auto';  
   const XML = 'xml';  
   const JSON = 'json';  
   const INI = 'ini';  
   const CSV = 'csv';  
   const DB  = 'pdo';  
      
   static private $instances;  
      
   static public function & getInstance($file, $type = self::AUTO)   
   {  
     if(! isset(self::$instances[$file]))   
     {  
       self::$instances[$file] = static::Load($file, $type);  
     }  
     return self::$instances[$file];  
   }  
   /**  
   * загружает 2D ассоциативный массив из файла (xml,json,ini,csv)   
   * или БД (*.pdo - ini-файл с ключами dsn, user, password, table, [driver_options] )  
   * @param string $filename  
   * @param const $type  
   * @return array  
   */  
   public static function Load($filename, $type=self::AUTO)  
   {  
     if(!file_exists($filename))  
       throw new Exception(__CLASS__.": The file $filename does not exist"); //todo: spec. exeption  
          
     if($type==self::AUTO)   
       $type = pathinfo($filename, PATHINFO_EXTENSION);  
          
     switch ($type) {  
       case self::INI:  
         return parse_ini_file($filename,true);  
       case self::CSV:  
         return static::readCSV($filename);  
       case self::JSON:  
         return json_decode(file_get_contents($filename),true);  
       case self::XML:  
         return static::objectToArray(simplexml_load_file($filename));  
       case self::DB:  
         $pdoini = parse_ini_file($filename);  
         $pdo = new PDO($pdoini['dsn'], $pdoini['user'], $pdoini['password'], is_array($pdoini['driver_options']) ? $pdoini['driver_options'] : null);  
         return static::LoadFromDB($pdo, $pdoini['table']);  
       default:  
         throw new Exception(__CLASS__.": Unknown file format ($type)"); //todo: spec. exeption  
     }  
   }  
   public static function Save($filename, $data, $type=self::AUTO)  
   {  
     $h = fopen($filename, "w");  
     if(!$h)  
       throw new Exception(__CLASS__.": Can't write file $filename"); //todo: spec. exeption  
          
     if($type==self::AUTO)   
       $type = pathinfo($filename, PATHINFO_EXTENSION);  
          
     switch ($type) {  
       case self::INI:  
         return static::writeIni($filename,$data);  
       case self::CSV:  
         return static::writeCSV($filename, $data);  
       case self::JSON:  
         return file_put_contents($filename,json_encode($data));  
       case self::XML:  
         return static::writeXML($filename,$data);  
       case self::DB:  
         $pdoini = parse_ini_file($filename);  
         $pdo = new PDO($pdoini['dsn'], $pdoini['user'], $pdoini['password'], is_array($pdoini['driver_options']) ? $pdoini['driver_options'] : null);  
         return static::SaveToDB($data, $pdo, $pdoini['table']);  
       default:  
         throw new Exception(__CLASS__.": Unknown file format ($type)"); //todo: spec. exeption  
     }  
   }  
   //---------- CSV ----------  
   static private function readCSV($filename)   
   {  
     $h = fopen($filename, "r");  
     if(!$h)  
       throw new Exception(__CLASS__.": Can't read file $filename"); //todo: spec. exeption  
     while(($data = fgetcsv($h)) !== FALSE)   
     {  
       $val = (count($data)>3) ? array_slice($data,2) : $data[2];  
       $ret[$data[0]][$data[1]] = $val;  
     }  
     fclose($h);  
     return $ret ?: array();  
   }  
   static private function writeCSV($filename, $data)   
   {  
     try  
     {  
       $h = fopen($filename, "w");  
       if(!$h)  
         throw new Exception(__CLASS__.": Can't write file $filename"); //todo: spec. exeption  
       foreach ($data as $sectname => $section)   
       {  
         foreach ($section as $key => $value)   
         {  
           if(is_array($value))  
             $out = array_merge(array($sectname, $key), $value);  
           else  
             $out = array($sectname, $key, $value);  
              
           if(fputcsv($h, $out)===false)   
             throw new Exception(__CLASS__.": Can't write file $filename"); //todo: spec. exeption  
         }  
       }  
       return true;  
     }  
     catch(Exception $e)  
     {  
       if($h) fclose($h);  
       throw $e;  
     }  
   }  
    
   //---------- XML ----------  
   private static function writeXML($filename, $data)  
   {  
     $xml = "<?xml version='1.0'?>";  
     $xml .= '<Root>'.static::array2XML($data).'</Root>';  
     return file_put_contents($filename,$xml);  
   }  
   private static function array2XML($data)  
   {  
     foreach ($data as $key => $value) {  
       if (is_array($value))   
         $value = static::array2XML($value);  
       if(is_numeric($key))  
         $ret.="<element index='$key'>$value</element>";  
       else  
         $ret.="<$key>$value</$key>";  
     }  
     return $ret;  
   }  
   //---------- DB ----------  
   public static function LoadFromDB(PDO $pdo, $table='Config')  
   {  
     $res = $pdo->query("select * from $table");  
     $rows = $res->fetchAll();  
     foreach ($rows as $value) {  
       $ret[$value['section']][$value['key']] = $value['value'];  
     }  
     return $ret;  
   }    
   public static function createTable(PDO $pdo, $table='Config')  
   {  
     $pdo->exec("create table if not exists $table (section varchar(32), key varchar(32), value varchar(256), primary key (section,key))");  
   }  
    
   public static function WriteToDB($data, PDO $pdo, $table='Config')  
   {  
     foreach ($data as $sectname => $section)   
       foreach ($section as $key => $value)   
       {  
         $values[] = "($sectname,$key,$value)";  
       }  
     $values = implode(',',$values);  
     return $pdo->exec("INSERT INTO $table (section,key,value) VALUES $values ON DUPLICATE KEY UPDATE value=VALUES(value)");  
   }  
   //---------- INI ----------  
   public static function writeIni($filename, $array2D)   
   {  
     $out = '';  
     foreach($array2D as $key => $value)   
     {  
       $out .= '['.$key."]\n";  
       $out .= static::write_section($value)."\n";  
     }  
     file_put_contents($filename, $out);  
   }  
   static function write_section(& $ini)   
   {  
     $ret = '';  
     //ksort($ini);  
     foreach($ini as $key => $val)   
     {  
       if (is_array($val))   
         foreach ($val as $k => $v)   
           $ret .= $key.'["'.$k.'"] = '.static::value2str($v)."\n";  
       else   
         $ret .= $key.' = '.static::value2str($val)."\n";  
     }  
     return $ret;  
   }  
   static function value2str($val)   
   {  
     if ($val === true)  return 'true';  
     if ($val === false) return 'false';  
     if ($val === null)  return 'null';  
     if (is_string($val)) return '"'.addslashes($val).'"';  
     return $val;  
   }  
   //---------- Util ----------  
   public static function objectToArray($obj)   
   {  
     $arr = (is_object($obj))?  
       get_object_vars($obj) :  
       $obj;  
    
     if(count($arr)==1 && isset($arr['element']))  
       $arr = $arr['element'];  
     foreach ($arr as $key => $val)   
     {  
       $arr[$key] = ((is_array($val)) || (is_object($val)))?  
         self::objectToArray($val) :  
         $val;  
     }  
    
     return $arr;  
   }  
   public static function array_flatten($array)   
   {  
     if (!is_array($array)) return FALSE;  
     $result = array();  
     foreach ($array as $key => $value)   
     {  
       if (is_array($value))   
         $result = array_merge($result, array_flatten($value));  
       else   
         $result[$key] = $value;  
     }  
     return $result;  
   }   
 }  
 ?> 

Комментариев нет:

Отправить комментарий