php: "while" egy CSV fájlban [megoldva]

Sziasztok.

egy CSV fájlom van, melyben a mezőelválasztó mezei vessző.

PHP-ban próbálom feldolgozni, de valami sehogyan sem sikerül. Azt szeretném, hogy ha egy sorban nem 6, hanem csak 4 mező van, ne várakozzon a script, hanem adja vissza a promptot. Ez most nem adja csak akkor, ha a csv 5-nél több elemű.


<?php

$csv = '1-,2-,3-,4-,5-,6-'; //ezzel lefut
/* $csv = '1-,2-,3-,4-,5-'; //ennel varakozik */

$i = 0;
while ($i <= 5) {
      $a = explode(',', $csv);
      if ( ! isset($a[$i])) 
         $a[$i] = null;
      else
       print_r($a[$i++]);
};
?>

Szerintetek hol nem néztem körül?

Hozzászólások

$a[$i++] = null

(hogy mindenképp növeld a ciklusváltozód)

Egyébként meg ha CSV fájlod van, akkor használd inkább az fgetcsv() [stringre nem jó, ezért kell hozzá a fájl] függvényt, hogy ténylegesen CSV-vel dolgozz (azért egy kicsit bonyolultabb annál, hogy sima explode-al fel tudd dolgozni, pl. mi van, ha az egyik mezőbe én beírok egy ,-t?)

A teljes feltöltésre meg:

$a = array_merge($a, array_fill(count($a), max(0, 6 - count($a)), null));

Szerk.: egy code tag és egy zárójel lemaradt.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

megnézem a fgetcsv()-t..
Amúgy nem egy komplett, hatalmas CSV fájlt akarok feldolgozni, hanem egy kódrészletben 4-8 adatot adok át egy függvénynek továbbfeldolgozásra, és az a 4-8 adat van egymástól vesszővel elválasztva.
Azért értelmeztem CSV-nek az adatot, mert a csv elnevezése eleve ezt rejti.
Viszont az fgetcsv-ről még nem olvastam, mindenképpen érdekel az is.

---
--- A gond akkor van, ha látszólag minden működik. ---
---

Hosszabb távon: Ha a másik függvényed a 4-8 adatot külön kell, hogy kezelje (és a másik függvényt is te készíted, így te határozod meg az interface-t), akkor szvsz. külön add át -- akár nyolc argumentumként

function foo($a, $b, $c, $d, $e = null, $f = null, $g = null, $h = null)

, akár egy tömbben

function foo(array $asd)

, akár vararg függvényként

function foo($a, $b, $c, $d) { $parameterek = func_get_args(); ... }

, tisztább interface-t kapsz.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

Hűha.

Egyrészt, a CSV-t ne a while cikluson belül robbantsd szét mezőkre, mert akkor a ciklus minden futásakor szétrobbantja, ami totálisan fölösleges. Elég egyszer szétrobbantani.

Másrészt, ha először szétrobbantod a CSV-t egy $a nevű tömbre, akkor nem kell statikusan 0-5-ig járatni a ciklust, hanem tudod annyiszor, ahány eleme van, pl.

for ($i = 0; $i < count($a); $i++) {
...
}

vagy

foreach ($a as $element) {
...
}

Harmadrészt, mivel a $a tömböt minden ciklusban újra felülírod az explode()-dal, ezért az if után következő értékadásnak semmi értelme nincs

Negyedrészt, mivel a $i csak az else ágban van növelve, ezért ha az előzőek miatt nem fut a program az else ágra, akkor máris végtelen ciklust alkottál,

Ötödrészt, az explode() nem igazán korrekt eszköz CSV beolvasására, vannak arra célfüggvények (str_getcsv és társai)

Hatodrészt, olvass el egy alapszintű programozást tanító könyvet, mert az első tíz oldal után annyival okosabb leszel, hogy megkíméled magad számos totálisan rossz koncepciótól.

1, 3: Ezek nekem hogy nem tűntek fel? Nagyon este van (mondjuk 1 kb. következik 3-ból).

2: Ha a kimeneti tömböt pont az előre ismert számú elemmel akarja feltölteni, akkor szvsz. jobb a fix számú oszlopra menni (ha az egy függvény lenne, a contract-ja szvsz. úgy szólna, hogy rekordokat ad vissza ennyi mezővel, azt meg illik betartani, még ha az input hibás/nem az elvárt is)

Ill. még egy, +1 az str_getcsv-re, mindig elfelejtem, hogy az is van.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

10 oldalban semmit sem lehet alaposan kiismerni.

Erre jutottam most, az eredeti rosszat átírva:


<?php
$csv = '1-,2-,3-,4-,5-';


      $a = explode(',', $csv);
      foreach ($a as $value)
      echo "elem: ".$value ;
?>

Ez pont megteszi amit akartam.
Azt hiszem már fel is fogtam hogy fentebb mit írtatok.

Kösz mindenkinek!

---
--- A gond akkor van, ha látszólag minden működik. ---
---

Már az explode-nál el van kúrva. fgetcsv mi a retkes búbánatért van ebben a hányás nyelvben, de most komolyan?

Mikor fogja már ez a szájbabaszott szakma megtanulni, hogy nem kezd el egyedileg tákolni CSV meg XML parsert, mikor van készen, gyárilag? Ezért egy nagy rák az egész IT.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Mi köze az életkornak ahhoz, hogy valaki egy szimpla egyszerű google keresést elengedjen az interneten, hogy adott, jól ismert problémát hogyan szokás megoldani jól egy adott nyelven? Ez nem életkor kérdése, hanem lustaság és szakmai igényesség kérdése.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nem vagyok fejlesztő. Hogy mi vagyok, ahhoz semmi közöd, de hozzászólásaidból ítélve nem volt túl jó napod.
A stílusod szerintem itt nem csak nálam veri ki a biztosítékot. Rövid leszek.

Én ide nem szórakozni és trollkodni járok mint te, mert nem érzem kocsmában magam.

Ha téged frusztrál, hogy ebben a topicban könyveim és az internet segítségével megoldottam egy számomra ismeretlen területen egy problémát, nem érdekel a nyomorod, nyilván amivel éppen foglalkozol, az neked nem jött épp össze (megjegyzem, nem érdekel, hogy esetleg mérnök vagy).

Mivel ezt a témát lezártnak tartom (odafent MEGOLDVA cimkét helyeztem el), nincs értelme idejárnod és trollkodni, mintha még mindig megoldatlan lenne a probléma.

Ha pedig senki sem állít le mert nincs cenzor, kénytelen vagyok mindezt én leírni nyilvánosan, szájbarágósan.

---
--- A gond akkor van, ha látszólag minden működik. ---
---

Igen, pontosan így készülnek az olyan kódok, amikor regexppel próbának meg feldolgozni XML-t, és str_replace-al próbálják meg kiváltani az iconv-ot. (Aztán jön a "miért küld hülye hangjegy karaktert az idióta partner" című szlogen.)

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Anyázás helyett nem lenne egyszerűbb elmagyarázni?
A kérdezőnek:
Nézzük először a csv fájlt.
A csv fájl egy szöveges fájl, amely egy fix oszlopszámú táblát ír le.
Az adatok valamilyen karakterrel vannak elválasztva egymástól (oszlop elválasztó vagy szeparátor, angolul column separator), általában ; , vagy tabulátor \t. Találkoztam már olyan fájllal, ahol pipeline-t (|) használtak.
Egy adott rekord végét a sor elválasztó vagy szeparátor, angolul row separator jelöli (ez Linux alatt jellemzően \n [kocsivissza], Windows alatt \r\n [sortörés, kocsivissza], ami a sor vége jel).
Magukat az oszlopokat/mezőket is le lehet zárni, leginkább a szöveges mezőket érdemes, ez általában ", angolul field enclosure. Erre azért van szükség, mert ha mező értéke tartalmaz oszlop elválasztó karaktert, akkor elcsúszik az oszlop sorrend.
Ezen kívül van még az escape karakter (ennek nem tudom a magyar megfelelőjét, de talán nem is baj), ezzel megadhatod, hogy az adott karaktert meg szeretnéd jeleníteni, nem pedig vezérlő karakterként használni.
Az fgetcsv és az str_getcsv nyilvánvalóan a fájlt és a fentebb leírt paramétereket kéri be.
Ha csak néhány rekord érdekes belőle, akkor neked az fgetcsv() kell.
Én az egyik kódomban ezzel a ciklussal olvasom fel egy csv tartalmát:

while(false !== ($row = fgetcsv($file, null, $delimiter, $enclosure, $escape))) {
// $row[0] a csv első oszlopa, $row[1] a második és így tovább
}
// csv feldolgozása utáni teendők

Ha bármi kérdésed van, kérdezz bátran!
-----------
"Pontban 0:00-kor nem nagyon szoktak véletlen dolgok történni"

Ugyan nem én vagyok az OP, és csak egy kicsit a nevezéktanra kérdeznék rá: a

$file

nem lenne jobb

$handle

-ként? Akkor a nevéből következne, hogy ott egy resource-nak kell lennie, egy

$file

-nak én simán adnék stringként egy fájlnevet.

Ill. a

null

-t is magyarázhatnád (egyébként a manual szerint az int-et vár, a defaultja 0, tehát 0-nak kéne lennie), hogy ha tudja, hogy legfeljebb milyen hosszú lehet egy sor, érdemes megadni a limitet, valamennyit gyorsít.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

Kösz a részletes dolgokat!
Eddig mindezt awk-val hajtottam végre, gyakorlatilag mindenütt (python, perl, c, php) ehhez viszonyítok mindent, mindenütt awk-san gondolkodom ha szövegfeldolgozásról van szó.
Mint fentebb írtam, már megoldottam a dolgot (szabványos, egyenlő oszlopszámú sorokból álló CSV helyett csak egy sort kellett feldolgoznom), de ha sok sorból álló fájlt kell használnom, ezt használom fel.

---
--- A gond akkor van, ha látszólag minden működik. ---
---

"Anyázás helyett nem lenne egyszerűbb elmagyarázni?"

És esetleg egy szem keresést megereszteni a témában? Ezercsillióan elmagyarázták mer ezertrillió helyen, hogy miért nem állunk neki saját parsert írni, ha van kész megoldás rá. Még, ha csak egy CSV is. (És főleg úgy nem, hogy sokan még azzal sincsenek tisztában, hogy mit lehet és mit nem lehet egy CSV-ben.)

Itt van pl. a klasszikussá vált poszt az XML/XHTML vs regexp témakörben: http://stackoverflow.com/a/1732454

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Értem, tehát az, hogy egyesek hajlandóak-e utánanézni ahhoz, hogy egy nyelven milyen librarykat, függvényeket szokás használni, az egyenértékű azzal, hogy egy egyébként leállított szolgáltatás hogyan marad kinn a weben.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nem 8 éve leállítva, csupán 8 éve nem ítam rá semmit. Ismerősöm, aki hostolta, valamikor az elmúlt évek során átrakta a MySQL-t egy külön gépre aztán valahogy így maradt.

De nem hiszem, hogy ez sokat változtatna azon, hogy az, aki nekiáll újraimplementálni teljesen feleslegesen, (sokszor részinformációk alapján) parsereket, az barom és nem szabadna hagyni fejleszteni.

De terelj csak nyugodtan, attól még nem lesz jobb az, amit te művelsz.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Az még nem biztos, hogy fejlesztő, aki programozással old meg problémát. Analógiát használva kb azt mondod: aki nem úgy beszél angolul, mint Shakespeare az ne beszéljen angolul, de legalább ne hagyják beszélni őt.

Az intelligencia sajátja a rugalmasság, nálad ezt nem vélem felfedezni, noha minden tiszteletem a tied, mint php kóder.
(Látszik, hogy ez az életed, hisz aki rossz kódot ír az személyesen téged sért meg balgaságával.)

Miután a hozzám hasonló ""php kóderek"" már nagyon sok hullámban elmondták az internet összes létező zugában, hogy miért rossz dolog feltalálni a spanyol viaszt (azt is rosszul), szerintem nem nekem kellene rugalmasságról magyarázni.

Az analógiád meg azért sántít, mert egyrészt nagyjából senki nem a Shakespeare-i angolt beszéli, másrészt abból kevesebb embernek lesz baja, mintsem, mikor egy phpistuka szarja miatt omlik be egy vállalat rendszere/törik meg a szervert/spammelnek viagrát etc., csak mert viszonylag alapvető dolgoknak nem nézett utána, hogy hogyan kellene jól csinálni.

De egyébként igen, ha valaki nem beszél rendesen angolul és ez potenciálisan veszélyforrás (teszem azt, orvos, gyógyszerész, mérgező anyagokkal dolgozik, olyan munkakörben van, ahol árthat másoknak, ha egy utasítást nem ért vagy nem érthetően ad ki, az ne dolgozzon angolul, míg össze nem szed annyi tudást, ami kell hozzá.)

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

A rugalmasság szerintem nem a spanyol viasz feltalálásában van, hanem annak továbbfejlesztésében. A PHP is OOP nyelv (na jó, OOP-ra kényszerített nyelv, korlátozott OOP funkciókkal), miért kell azt az istenverte XML/CSV/JSON/whatever parsert mind a 30 embernek újra és újra megírni és kibővíteni, mikor van egy tesztelt, támogatott, jól működő alap, amit továbbfejleszthetnek?

-----------
"Pontban 0:00-kor nem nagyon szoktak véletlen dolgok történni"

De minek kell sajat formátum és minek kell sajat kód? És miből feltételezés, hogy hibamentes lesz?

Kivetnivalók:
- Valószínűleg hibásabb lesz, mint egy meglévő implementáció.
- Nem biztos, hogy minden esetet lekezelsz.
- Nem szabványos eszköz, nehezebb átadni, átvenni, kommunikálni más sgoftverekkel.
- Növeli a fejlesztési, karbantartási költségeket.
- Ezzel együtt a kódod komplexitását is azzal, hogy egy önálló egység helyett a magad kódbázisát gyarapítod.
- Megoldott probléma.
- Ameddig ezzel foglalkozol, addig se a tényleges feladat megoldásán dolgozol.

Gyakorlatilag tanuláson, gyakorláson kívül nincs értelme saját formátumot feltalálni, saját parsert írni. Utóbbi esetben viszont kezdje azzal az ember, hogy elolvassa az ide vonatkozó szabványt, RFC-t, stb. De akkor nem is explode-dal meg regexppel fog szerencsétlenkedni.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Gyakorlatilag tanuláson, gyakorláson kívül nincs értelme saját formátumot feltalálni, saját parsert írni.

Azért előferdülhet, hogy van értelme:
- Vendor lock-int akarsz csinálni, a legjobb megoldás protokoll-szinten zárni mindent [MS-nek bejött :) ] - saját formátum
- Vendor lock-int akarsz csinálni, egy másik nagyon jó megoldás a dokumentálatlan fájl formátumok kitalálása [MS-nek és sokan másoknak bejött :) ] - saját formátum
- Új csereformátumot tervezel. Ha Crockford követi a fenti elveidet, ma nincs pl. JSON. - saját formátum
- Adott fájlformátumra nincs adott nyelven implementáció - saját kód

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

A Vendor lock-in-ről annyit, hogy nem, nem jött be az MS-nek. Olyannyira nem, hogy egyre inkább a nyílt forráskód felé orientálódnak. Ha nekik nem jött be, akkor másoknak sem, legjobb esetben csak az anyját szidják, rosszabb esetben megkeresik és levágják mind a 10 ujját/két kezét, hogy ne tudjon még egyszer ilyen gaztettet véghez vinni. Nem arról van szó, hogy nincs szükség csereformátumra, de ha mindenki legyártja a saját formátumát, akkor abból borzasztó nagy káosz lenne. Szerintem mindenki elvan az XML-JSON párossal, a legtöbb nyelvben built-in támogatás van rá.

-----------
"Pontban 0:00-kor nem nagyon szoktak véletlen dolgok történni"

Mai rohanó világunkban már félek feltenni kérdést, mert a végén gyógyszerészettel, shakespeare-i beszédmód imitálásával vádolnak.
Nem olvastam volna minderről, ha valaki el nem küldi nekem a linket.
Ma jó napom volt.
Különben, mondat közepén a ,,shakespeare-i'' szó melléknévként kisbetű. Erre meg én vagyok allergiás, pedig nem vagyok magyartanár..

---
--- A gond akkor van, ha látszólag minden működik. ---
---

Különben, mondat közepén a ,,shakespeare-i'' szó melléknévként kisbetű. Erre meg én vagyok allergiás, pedig nem vagyok magyartanár..

<troll>
A mondatkezdő szó esetet leszámítva mindenhol, pl. mondat végén is ;)
</troll>

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)