2009-08-03 10 views
1

Ich habe eine .txt Datei mit Produktdaten, die ich in PHP lesen möchte. Jede Zeile enthält ein Produkt und die Produktdetails (Nummer, Name und Preis) sind durch Tabulatoren getrennt. Wie Sie unten sehen können, stimmt es nicht immer, dass die Preise aufgrund des Längenunterschieds für die Produktnamen vertikal gut ausgerichtet sind. Die Daten sehen wie folgt aus:php Produktdaten txt Datei lesen

ABC001 an item description $5.50 
XYZ999 an other item $6 
PPP000 yet another one $8.99 
AKA010 one w a longer name $3.33 
J_B007 a very long name, to show tabs $99 

(ich wusste nicht, wie die Registerkarten zu zeigen, so dass sie Räume im Beispiel oben, aber in der realen Datei, es sind echt Tabs)

Was ist der effizienteste Weg, dies zu tun? (Übrigens ist es eine Remote-Datei) Ich würde gerne ein Array haben, um die Produktdaten pro Produkt enthält:

$product['number'], $product['name'] and $product['price'] 

Vielen Dank!

Antwort

2

1) Der einfachste Weg, die Verwendung der Datei ist(), um alle Zeilen in ein Array zu laden (es sei denn, die Datei wirklich groß , dann würde ich einen anderen Ansatz betrachten).

2) aufgeteilt, jede Zeile durch Register ("\ t" character)

3) "Format" die Array-Spalten, wie Sie wollen.

Beispiel Schnipsel:

$productsArray = file($productsFileName, FILE_IGNORE_NEW_LINES); 

foreach ($productsArray as $key => &$product) { 
    $arr = explode("\t", $product); 
    $product = array('number' => $arr[0], 'name' => $arr[1], 'price' => $arr[2]); 
} 

var_dump($productsArray); 
+0

Was halten Sie für wirklich groß? Es enthält ungefähr 2000 Zeilen, denke ich.Was ist der andere Ansatz, den Sie berücksichtigen würden? – Fortega

+0

2000 Zeilen klingt gut. Für etwas über ein paar Megabytes würde ich nicht das * ganze * Produkte-Array im Speicher haben, sondern iteriere stattdessen durch die Elemente - wahrscheinlich mit fgets(), um einzelne Zeilen aus der Datei zu bekommen. –

3

Sie könnten die Datei zeilenweise lesen (z. B. mit der Funktion file, die jede Zeile in eine Zeile eines Arrays bringt).

Und dann verwenden explode auf jeder dieser Zeilen, um die Felder zu trennen.

$data_of_line = explode("\t", $string_line); 

Mit "\t" (tabellarische ") als Trenn

Sie würden dann haben $data_of_line[0] mit der Nummer, $data_of_line[1] den Namen und $data_of_line[2] der Preis.

1
$fileArr = file('path.to.your.file.txt'); 

$productsData = array(); 

for ($i = 0; $i < count($fileArr); $i++) { 
    $lineData = preg_match('/^(\w{3}\d{3})\s+(.*)\s+\$(\d+(\.\d+))$/', $fileArr[$i], $matches); 
    $productsData[] = array(
     'number' => $matches[1], 
     'name' => $matches[2], 
     'price' => $matches[3] 
    ); 
} 

Diese slo wird Die Verwendung explodiert, aber es kann auch Dateien analysieren, die mehr als nur eine Registerkarte als Trennzeichen zwischen Werten haben. Plus Sie müssen nicht $ Zeichen aus den Preisen entfernen. Wenn Sie $ Schild mit dem Preis zu halten wan't sollten Sie diese Regex statt:

'/^(\w{3}\d{3})\s+(.*)\s+(\$\d+(\.\d+))$/' 
+0

ist \ s bedeuten ein Registerkarte in Regex? der Produktcode kann auch etwas anderes sein, aber das kann ich ändern. – Fortega

+0

\ s bedeutet Leerzeichen, also Tabstopps, Leerzeichen, Zeilenumbrüche und Zeilenumbrüche. Da wir jedoch nur eine Zeile nach der anderen abgleichen, werden nur Leerzeichen und Tabulatoren abgeglichen. Dies ist für den Fall, dass jemand einen Fehler gemacht und Werte mit Leerzeichen anstelle von Tabs getrennt, dieses Skript wird es möglich machen, die Werte auch davon zu bekommen, während "explodieren" Lösung wird abstürzen. – RaYell

2

fgetcsv() eine gute Funktion

Check-out ist das Beispiel von http://us3.php.net/manual/en/function.fgetcsv.php, hier ist eine leicht modifizierte Version:

$products = array(); 
$handle = fopen("products.txt", "r"); 

while (($data = fgetcsv($handle, 1000, "\t")) !== FALSE) { 
    $products[] = array(
     'number' => $data[0], 
     'name' => $data[1], 
     'price' => $data[2] 
    ); 
} 
fclose($handle);