Çok boyutlu bir diziye düz dosya veritabanı bilgilerini Ayrıştırma

3 Cevap php

Ben büyük bir benzer çok boyutlu diziye düz dosya veritabanı bilgilerini ayrıştırma için bir sınıf yapmak istiyorum. Ben aşağıdaki gibi python-vari biçimi bir tür veritabanı biçimlendirme fikri vardı:

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

Ben bu ayrıştırmak ve anahtarları / değerlerini içine atmak ayrıştırma sırasında inşa ve dizi yapmaya çalışıyorum, ve ben bunu çok dinamik ve genişletilebilir olmak istiyorum. Ben çok farklı teknikler denedim ve ben bu girişimleri her şaşkına oldum. Bu benim en yeni:

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);
}

Ben dürüst nereye buradan gitmek için hiçbir fikrim yok. Beni en çok rahatsız eden şey burada var $this->c["main"]["sub"]["etc"] yolu gibi çok boyutlu değerlerini ayarlıyor. Hatta yapılabilir mi? Nasıl Aslında yuva veri olarak diziler db dosyasında yuvalanmış olabilir?

3 Cevap

Bu, tüm sizin "düz dosya" olmak istiyorum nasıl insan okunabilir bağlıdır gidiyor.

Insan okunabilir ister misiniz?

  • XML
  • Yaml

Yarı Okunabilir?

  • JSON

Gerçekten insan okunabilir değil mi?

  • Tefrika PHP (aynı zamanda PHP-sadece)
  • MySQL Damper

Kendi biçimini yazma acı olacak. Eğer akademik deneyim için sadece bunu yapmak istemiyorsanız, o zaman ben aldırma söylüyorlar.

JSON sizin için mutlu bir ortam olabilir gibi görünüyor.

$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 ) ) );

Sen json_format() fonksiyonunu here, alabilirsiniz kolay insan okuma için hangi sadece güzel-biçimleri. Eğer insan-okunurluk umurumda değil, bunu atlayabilirsiniz.

Peki, could serialize kullanın ve unserialize ama bu doğru, hiç eğlenceli olurdu? Bunu özellikle bu amaç için tasarlanmış biçimleri kullanıyor olmalıdır, ancak egzersiz uğruna, ben denemek ve ben ile gelip ne görürsünüz.

Ikiniz Flatfile içinde veri türleri çeşitleri, anahtar-değer çiftleri ve diziler var gibi görünüyor. anahtar-değer çiftleri tek tırnak çift ve bir alttaki kolon ile tırnak ve diziler iki set ile belirtilir. Eğer dosyada geçmesi gibi, her satırı ayrıştırmak ve neyi temsil ettiğini belirlemeniz gerekir. Bu düzenli ifadelerle kolay. Zor kısmı biz gidiyoruz düzeyde takip etmek ve buna göre hareket etmektir. Burada sağlanan ağaç ayrıştırır bir fonksiyon:

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

Böylece ben nasıl çalıştığını daha detaylı girmeyeceğim, ama biz diziye derin ilerleme olarak kısa, önceki seviye bir referans saklanır $open ve. İşte gösterimi kullanarak daha kompleks bir ağaç:

"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"

Ve bu dosyayı ayrıştırmak için şunu kullanabilirsiniz:

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

Ve bu çıkışı olur:

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
				)    
			)    
		)    
	)    
)

Benim sınama dosyası tüm üsleri kapsar sanırım, ve should bozmadan çalışır. Ama ben herhangi bir garanti vermez.

Bu gösterimle Flatfile için çok boyutlu bir dizi Dönüşümü okuyucuya bir alıştırma olarak kalacak :)

Eğer sadece bir dosya için bir dizi yüklemek ve kaydetmek istiyorsanız ...

$content = "<?php\nreturn " . var_export($array, true) . ';';
/*save to configfile.php */
$array = include('configfile.php');