[PHP] Bestand inlezen naar array

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • RAJH
  • Registratie: Augustus 2001
  • Niet online
Probleem
Ik ben bezig om data uit een automatisch inspectie systeem in een MySQL database te krijgen, maar nu wil het mij niet lukken om de arrayindex op zo'n manier te verhogen dat de bij elkaar horende data ook bij elkaar in een array komt.

Databestand (test.txt)
Databestand

PHP
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$handle = @fopen("test.txt", "r");
if ($handle) {
    $iEmptyBufferCount = 0;
   while (!feof($handle))
   {
        $buffer = fgets($handle, 4096);

                // buffer is een carriage return
        if (ord($buffer) == 13)
        {
            $iEmptyBufferCount++;
        }
        elseif (is_int($iEmptyBufferCount / 2))
        {
            // Dan moet dit dus de info zijn
            $arInfo[0][] = trim($buffer);
        }
        else
        {
            // Dan moeten dus dit de fouten zijn
            $sTrimmed = trim($buffer, "\n \r");
            $arTemp = explode("\t", $sTrimmed);

            if (ord($arTemp[7]) != 0 and $arTemp[7] != "_NOTE")
            {
                $arInfo[0]['errors'][] = $arTemp;
            }
        }

   }
   fclose($handle);
}

echo '<pre>';
print_r($arInfo);


Hoe kan ik de index $arInfo[0] verhogen zodat de errors bij de juiste info in de array komt? Ik heb geprobeerd om een counter tijdens de loop te laten verhogen, maar dat werkt natuurlijk niet omdat de loop per regel doorlopen wordt.

Ook heb ik het volgende geprobeerd
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
$handle = @fopen("test.txt", "r");
if ($handle) {
    $iEmptyBufferCount = 0;
    $iArrayIndex = 0;
   while (!feof($handle))
   {
        $buffer = fgets($handle, 4096);

        /**
        * Als de buffer niet leeg is en er nog twee
        * lege buffers zijn gevonden, zet dan de
        * info data in de array
        **/

        if (ord($buffer) != 13 and $iEmptyBufferCount < 2)
        {
            $arInfo[0][] = trim($buffer);
        }

        /**
        * Als de buffer leeg is en er nog geen twee
        * lege buffers zijn gevonden, verhoog dan
        * de $iEmptyBufferCount met 1
        **/

        elseif (ord($buffer) == 13 and $iEmptyBufferCount < 2)
        {
            $iEmptyBufferCount++;
        }

        /**
        * Aslde buffer niet leeg is en er zijn twee
        * lege buffers gevonden, zet dan de errordata in
        * de array
        **/

        elseif (ord($buffer) != 13 and $iEmptyBufferCount == 2)
        {
            $sTrimmed = trim($buffer, "\n \r");
            $arTemp = explode("\t", $sTrimmed);

            if (ord($arTemp[7]) != 0 and $arTemp[7] != "_NOTE")
            {
                $arInfo[0]['errors'][] = $arTemp;
            }
        }

        /**
        * Als de buffer leeg is en er zijn twee
        * lege buffers gevonden, verhoog dan
        * de $iEmptyBufferCount met 1
        **/

        elseif (ord($buffer) == 13 and $iEmptyBufferCount == 2)
        {
            $iEmptyBufferCount++;
        }
   }
   fclose($handle);
}

echo '<pre>';
print_r($arInfo);

Dit werkt alleen voor de eerste en om het met alle data te laten werken moet ik de $iEmptyBufferCount vast in de broncode zetten, wat dus totaal niet werkzaam is :/

Kan iemand mij een duw in de goede richting geven?

[edit]
Ik heb het databestand (test.txt) nu iets duidelijker aangegeven ;)

Ik heb file() ook al geprobeerd, maar dan blijft mijn probleem hetzelfde, namelijk hoe kan ik er voor zorgen dat de fouten bij de info blijft?

[ Voor 13% gewijzigd door RAJH op 09-05-2006 09:25 ]


Acties:
  • 0 Henk 'm!

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 08-06 22:31

Gerco

Professional Newbie

Ik weet niet hoe je tekstbestand eruit ziet, maar als dat een regelgebaseerde tekstfile is, zou ik eens naar de functie file() kijken. De data kun je dan in PHP veel makkelijker sorteren en vergelijken dan tijdens het inlezen.

[edit]
Na je databestand gezien te hebben, zou ik het met een regex aanpakken. Lees die hele file in met file_get_contents() en haal er daarna een regex overheen met preg_match_all() om alle matches (dataregels) in een array te krijgen.

Je zou natuurlijk ook file() kunnen gebruiken en dan per regel een regex eroverheen halen om te zien of het een dataregel is, maar met preg_match_all() heb je (met een goede regex) gelijk al je data apart en gesorteerd in kolommen staan. Dan kun je gelijk verder met het inserten in MySQL.

[ Voor 62% gewijzigd door Gerco op 09-05-2006 09:30 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Acties:
  • 0 Henk 'm!

  • RAJH
  • Registratie: Augustus 2001
  • Niet online
De dikgedrukte zaken ben ik alleen nodig uit het databestand en wordt het dan niet tergend langzaam als ik voor elke dikgedrukte string een verschillende regex gebruik?

[b]06/02/06 13:38:28[/b]
[b]PEE307-505_508_540SGA[/b]
 [ 2006.2.6 13:38:27 ]
Total PCBs checked[342]
Total NG PCBs     [272]
Current result (check 650 NG 4/23) Spent time 6
BarNum ([b]1035650[/b])

SYM	TTL	NG	NG_ID	_X	_Y	_NUM	_NOTE
	342	1	0	5204	8290	-50	
	342	0	0	2849	4204	-132	
	342	1	0	3091	2480	-138	
	[b]11	2	0	11209	7575	264	Short-circuit[/b]
	11	0	0	14436	6572	-306	
	11	1	0	14208	8306	-312	
	11	0	0	11217	7356	-317	
	11	1	0	18712	8294	-400	
	11	1	0	19375	6285	-406	
	[b]11	3	0	19566	6269	413	Shape mismatch (by sidelight)[/b]
	11	1	0	23208	8306	-488	
	[b]11	2	0	9914	3210	527	Short-circuit and fillet NG.[/b]
	11	0	0	7345	4196	-570	
	11	1	0	7591	2480	-576	
	11	0	0	9914	2980	-582	
	11	0	0	13792	4241	-645	
	11	0	0	11849	4196	-656	
	11	1	0	12091	2480	-662	
	11	1	0	16591	2480	-748	
	11	1	0	20853	4196	-828	
	[b]11	1	0	20211	4507	845	Shape mismatch (by sidelight)[/b]

Acties:
  • 0 Henk 'm!

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 08-06 22:31

Gerco

Professional Newbie

Die eerste twee kun je geen regex voor gebruiken, daar wil je zowiezo de hele regel hebben. Die dataregels zou wel kunnen, maar als je toch al van boven naar onder door de regels moet lopen, zou je net zo goed een gewone explode() kunnen gebruiken en kijken of het laatste veld gevuld is. Dat BarNum is makkelijk met een regex uit de string te vissen, handiger dan te klooien met substr().

Let op, volledig uit de losse hand ingeklopte, ongeteste, zelfs niet eens geparste code. Runnen is volledig op eigen risico :D Dit gaat er overigens vanuit dat je dataregels tab gescheiden zijn en ik zal vast wel ergens verkeerd geteld hebben, maar dat mag de pret natuurlijk niet drukken.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$i=0;
$data=file("test.txt");
while($i<sizeof($data)) {
  // Eerste twee regels inlezen:
  $datum = trim($data[$i++]);
  $code = trim($data[$i++]);

  // Skip 4 regels en lees dan Barnummer
  $i+=4;
  $matches = Array();
  if(preg_match("/^BarNum \((\d+)\)/", $data[$i++], $matches)) {
    $barnum = $matches[1];
  }

  // Lees nu alle dataregels met een fout
  $i++;
  
  while(trim($data[++$i]) != "") {
    $velden = explode("\t", $data[$i]);
    if(trim($velden[6])!="") {
      // Sla deze regel op in de database
    }
  }

  $i++;
}

[ Voor 24% gewijzigd door Gerco op 09-05-2006 10:03 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Acties:
  • 0 Henk 'm!

  • RAJH
  • Registratie: Augustus 2001
  • Niet online
Eén foutje mag best if(trim($velden[6])!="") moet if(trim($velden[7])!="") zijn. Voor de rest werkt het precies zoals ik het wil hebben :D. Ik had ondertussen al zes verschillende testcases gemaakt, maar hier was ik niet opgekomen.

Heel erg bedankt voor de oplossing _/-\o_.