2009-12-11 36 views
0

我想创建一个类来将平面文件数据库信息解析为一个大的类似多维数组。我曾在一个排序蟒式的格式格式化数据库的想法如下:将平面文件数据库信息解析到多维数组中

"tree #1": 
    "key" "value" 
    "sub-tree #1": 
     "key" "value" 
     "key #2" "value" 
     "key #3" "value" 

我试图让它解析这一点,并建立和阵列,同时在分析它的键/值丢进去,我希望它是非常动态和可扩展的。我尝试过很多不同的技术,而且我一直都被困在这些尝试中。这是我最近的:

function parse($file=null) { 
    $file = $file ? $file : $this->dbfile; 

    ### character variables 

    # get values of 
    $src = file_get_contents($file); 
    # current character number 
    $p = 0; 

    ### array variables 

    # temp shit 
    $a = array(); 
    # set $ln keys 
    $ln = array("q"=>0,"k"=>null,"v"=>null,"s"=>null,"p"=>null); 
    # indent level 
    $ilvl = 0; 

    ### go time 

    while (strlen($src) > $p) { 
     $chr = $src[$p]; 
     # quote 
     if ($chr == "\"") { 
      if ($ln["q"] == 1) { // quote open? 
       $ln["q"] = 0; // close it 
       if (!$ln["k"]) { // key yet? 
        $ln["k"] = $ln["s"]; // set key 
        $ln["s"] = null; 
        $a[$ln["k"]] = $ln["v"]; // write to current array 
       } else { // value time 
        $ln["v"] = $ln["s"]; // set value 
        $ln["s"] = null; 
       } 
      } else { 
       $ln["q"] = 1; // open quote 
      } 
     } 

     elseif ($chr == "\n" && $ln["q"] == 0) { 
      $ln = array("q"=>0,"k"=>null,"v"=>null,"s"=>null,"p"=>null); 
      $llvl = $ilvl; 

     } 
     # beginning of subset 
     elseif ($chr == ":" && $ln["q"] == 0) { 
      $ilvl++; 
      if (!array_key_exists($ilvl,$a)) { $a[$ilvl] = array(); } 
      $a[$ilvl][$ln["k"]] = array("@mbdb-parent"=> $ilvl-1 .":".$ln["k"]); 
      $ln = array("q"=>0,"k"=>null,"v"=>null,"s"=>null,"p"=>null); 
      $this->debug("INDENT++",$ilvl); 
     } 
     # end of subset 
     elseif ($chr == "}") { 
      $ilvl--; 
      $this->debug("INDENT--",$ilvl); 
     } 
     # other characters 
     else { 
      if ($ln["q"] == 1) { 
       $ln["s"] .= $chr; 
      } else { 
       # error 
      } 
     } 
     $p++; 
    } 
    var_dump($a); 
} 

我真的不知道该从哪里出发。让我最困扰的事情是按照我在这里的方式设置多维值,如$this->c["main"]["sub"]["etc"]。它可以完成吗?当数据嵌套在数据库文件中时,我怎样才能真正嵌套数组?

+2

我一直在回答你的问题,直到你开始谈论你将如何格式化数据。没有不敬的意图,但是当SQLITE,MySQL,PostgreSQL,JSON,YAML,Pickle和其他几个人坐在那里等着你使用时,这是疯狂的? – gahooa

+0

你的平板数据是什么样的?或者,你的第一个代码片段就是这样吗? –

+0

@gahooa同意。 XML,序列化的PHP,CSV等。制作自己的平面文件格式是疯狂的。 –

回答

0

那么,你可能使用serializeunserialize但这不会很好玩,对吗?你应该使用专门为此目的设计的格式,但为了锻炼,我会尝试看看我能想出什么。

在flatfile,键值对和数组中似乎有两种数据类型。键值对用两组引号和数组用一对引号和后面的冒号表示。在您浏览文件时,您必须解析每一行并确定它代表的内容。正则表达式很简单。最难的部分是跟踪我们所处的级别并采取相应的行动。下面是分析你所提供的树的功能:

function parse_flatfile($filename) { 
    $file = file($filename); 

    $result = array(); 
    $open = false; 
    foreach($file as $row) { 
     $level = strlen($row) - strlen(ltrim($row)); 
     $row = rtrim($row); 
     // Regular expression to catch key-value pairs 
     $isKeyValue = preg_match('/"(.*?)" "(.*?)"$/', $row, $match);   
     if($isKeyValue == 1) { 
      if($open && $open['level'] < $level) { 
       $open['item'][$match[1]] = $match[2]; 
      } else { 
       $open = array('level' => $level - 1, 'item' => &$open['parent']);     
       if($open) { 
        $open['item'][$match[1]] = $match[2]; 
       } else { 
        $result[$match[1]] = $match[2]; 
       } 
      } 
     // Regular expression to catch arrays 
     } elseif(($isArray = preg_match('/"(.*?)":$/', $row, $match)) > 0) { 
      if($open && $open['level'] < $level) { 
       $open['item'][$match[1]] = array(); 
       $open = array('level' => $level, 'item' => &$open['item'][$match[1]], 'parent' => &$open['item']); 
      } else { 
       $result[$match[1]] = array(); 
       $open = array('level' => $level, 'item' => &$result[$match[1]], 'parent' => false); 
      } 
     }  
    }  
    return $result; 
} 

我不会去到更详细的关于如何工作的,但它的短,因为我们进步深入阵列,上一级存储在参考$open等。下面是使用你的符号更复杂的树:

"tree_1": 
    "key" "value" 
    "sub_tree_1": 
     "key" "value" 
     "key_2" "value" 
     "key_3" "value" 
    "key_4" "value" 
    "key_5" "value" 
"tree_2": 
    "key_6" "value" 
    "sub_tree_2": 
     "sub_tree_3": 
      "sub_tree_4": 
       "key_6" "value" 
       "key_7" "value" 
       "key_8" "value" 
       "key_9" "value" 
       "key_10" "value" 

并解析该文件,你可以使用:

$result = parse_flatfile('flat.txt'); 
print_r($result); 

这将输出:

Array 
(
[tree_1] => Array 
    (
    [key] => value 
    [sub_tree_1] => Array 
     (
     [key] => value 
     [key_2] => value 
     [key_3] => value 
     )  
    [key_4] => value 
    [key_5] => value 
    )  
[tree_2] => Array 
    (
    [key_6] => value 
    [sub_tree_2] => Array 
     (
     [sub_tree_3] => Array 
      (
      [sub_tree_4] => Array 
       (
       [key_6] => value 
       [key_7] => value 
       [key_8] => value 
       [key_9] => value 
       [key_10] => value 
       )  
      )  
     )  
    )  
) 

我想我的测试文件套所有的基地,它应该工作不破。但我不会提供任何保证。

转换一个多维数组使用这个符号来FLATFILE将作为练习留给读者:)

+0

谢谢!我实际上不知道变量之前做了什么&,这对我正在努力完成的事情有很大的帮助。是的,我知道我想要完成的是不切实际的。将该数组转换为平面文件应该是蛋糕! :) – ADFDSADSA

1

这一切都将取决于你如何人类可读希望你的“平面文件”是。

想要人类可读?

  • XML
  • YAML

半人类可读?

  • JSON

不是真的人类可读?

  • 系列化PHP(PHP也只)
  • Mysql的自卸

编写您自己的格式将是痛苦的。除非你想纯粹为学术经历做这个,否则我说不要打扰。

看起来像JSON可能是您的快乐媒介。

$configData = array(
    'tree #1' => array(
     'key'   => 'value' 
     , 'sub-tree #1' => array(
      'key' => 'value' 
     , 'key #2' => 'value' 
     , 'key #3' => 'value' 
    ) 
) 
); 

// Save config data 
file_put_contents('path/to/config.json', json_format(json_encode($configData))); 

// Load it back out 
$configData = json_decode(file_get_contents('path/to/config.json'), true); 

// Change something 
$configData['tree #1']['sub-tree #1']['key #2'] = 'foo'; 

// Re-Save (same as above) 
file_put_contents('path/to/config.json', json_format(json_encode($configData))); 

你可以得到json_format()功能here,这只是漂亮的格式,方便人阅读。如果你不关心人的可读性,你可以跳过它。