Php 将平面文件数据库信息解析为多维数组
我想创建一个类,用于将平面文件数据库信息解析为一个大型的类似多维数组。我的想法是将数据库格式化为类似python的格式,如下所示:Php 将平面文件数据库信息解析为多维数组,php,arrays,multidimensional-array,flat-file,Php,Arrays,Multidimensional Array,Flat File,我想创建一个类,用于将平面文件数据库信息解析为一个大型的类似多维数组。我的想法是将数据库格式化为类似python的格式,如下所示: "tree #1": "key" "value" "sub-tree #1": "key" "value" "key #2" "value" "key #3" "value" 我试图让它在解析时解析这个,构建和数组,将键/值放入其中,我希望它是非常动态和可扩展的。我尝试过许多不同的技术,但每次都被难倒
"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”]
我在这里的设置方式。甚至可以做到吗?当数据嵌套在db文件中时,我如何实际嵌套数组呢?好吧,你可以使用,但那不会很有趣,对吗?您应该使用专门为此目的而设计的格式,但为了练习,我将尝试看看我能想出什么
在平面文件中似乎有两种数据类型,键值对和数组。键值对用两组引号表示,数组用一对引号和后面的冒号表示。在浏览文件时,必须解析每一行并确定它代表什么。使用正则表达式很容易。困难的部分是跟踪我们所处的水平,并据此采取行动。下面是一个解析您提供的树的函数:
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;
}
要解析该文件,您可以使用:
$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
)
)
)
)
)
我想我的测试文件涵盖了所有的基础,它应该可以正常工作而不会中断。但我不会做出任何保证
使用此符号将多维数组转换为平面文件将留给读者作为练习:)这取决于您希望“平面文件”的可读性 想要人类可读吗
- XML
- 亚马尔
- JSON
- 序列化PHP(也仅限于PHP)
- Mysql转储
$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\u format()
函数,它的格式非常漂亮,便于人们阅读。如果你不关心人的可读性,你可以跳过它。在你开始谈论如何格式化数据之前,我一直在考虑你的问题。没有不尊重的意思,但当SQLITE、MySQL、PostgreSQL、JSON、YAML、Pickle和其他多少人坐在那里等待您使用时,这是疯狂的。您的平面数据是什么样子的?还是你的第一个代码片段就是这样?@gahooa同意。XML、序列化PHP、CSV等。制作自己的平面文件格式是疯狂的。@Peter Bailey:第一段@gahooa:SQL与您只需更改数组值,然后使用函数将数组数据保存到文件的方式相比,非常麻烦。这是否是一个好主意并不重要。谢谢!事实上,我不知道在变量出现之前,安培数做了什么,这对我正在努力实现的目标是一个巨大的帮助。是的,我知道我想要完成的是不现实的。将该数组转换为平面文件应该很简单!:)
$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 ) ) );