Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 将平面文件数据库信息解析为多维数组_Php_Arrays_Multidimensional Array_Flat File - Fatal编程技术网

Php 将平面文件数据库信息解析为多维数组

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" 我试图让它在解析时解析这个,构建和数组,将键/值放入其中,我希望它是非常动态和可扩展的。我尝试过许多不同的技术,但每次都被难倒

我想创建一个类,用于将平面文件数据库信息解析为一个大型的类似多维数组。我的想法是将数据库格式化为类似python的格式,如下所示:

"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转储
编写自己的格式会很痛苦。除非你纯粹是为了学术经验,否则我说不用麻烦了

看来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\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 ) ) );