valideren csv input
Ik ben reeds enige tijd aan het googlen om een goede oplossing te vinden voor het volgende:
Ik ben bezig met een website voor iemand die regelmatig grote hoeveelheden gegevens in een mysql database moet vervangen. Het programma dat hij op zijn computer gebruikt (Microsoft Access) heeft niet meteen de functies aan boord om deze taken uit te voeren. Ik laat hem de tabellen exporteren als csv waardes die hij dan in de website kan laden (er moeten hier en daar veranderingen gebeuren in de gegevens en een aantal zaken toevoegen, niet 'gewoon' synchroniseren, want dat gaat gewoon met access natuurlijk).
Gisteren gebeurde het dat Access een foutje maakte bij het aanmaken van het csv-bestand (Ja, het kan... ), hij probeert dit foutieve bestand in te laden... eerst wordt de database leeggemaakt, dan de nieuwe waardes erin, maar dat laatste ging dus niet goed, gevolg: website helemaal plat.
Mijn punt: hoe kan ik nakijken of er foutjes in de csv zitten alvorens deze te verwerken zodat dit niet meer kan gebeuren. Ik heb al gedacht om de gegevens eerst in een andere database te laden, wanneer dit faalt niet verder te gaan met het verwerken en zo de site intact laten, maar dit lijkt mij nogal omslachtig, ik zou liever een goede methode hebben om de csv te valideren.
Ik heb gezocht naar een Regular Expressions hiervoor maar ben nergens geraakt.
Eigenschappen van de csv: scheidingsteken: ","
Sommige waardes worden encapsulated met: "
Er moeten 3 waardes zijn gescheiden door komma's, dan moet er een /n komen
Iemand die mij een hint kan geven?
Dank bij voorbaat.
Wil je het perse met PHP doen (geautomatiseerd) of kan dit ook client side?
Als je het importeert met de functie die hierboven wordt beschreven, dan kan je daarna eerst de array doorlopen en je checks doen en mits je geen fouten vindt dan pas de db updaten.
Dit is wat ik heb ondertussen, wel nog wat onhandig maar het komt wel goed zo denk ik
Edit:
script verwijderd, nieuwe versie in volgende post
Gewijzigd op 05/06/2010 13:50:05 door Hans Vereyken
Code (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
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
<?php
function validCsv ($csv, $regexps) {
$data = nl2br ($csv); //nl2br
$numberOfLines = substr_count($data, "<br />"); //Count occurances of <br />
$result[0] = true;
$result[1] = $numberOfLines;
$result[2] = "";
$lineNumber = 0;
while ($lineNumber < $numberOfLines) {
$lineNumber++;
list ($lineString, $data) = explode ("<br />", $data, 2); //First line in $lineString, rest in $data
$lineArray = str_getcsv ($lineString, ","); // split values of $lineString in array in $lineArray
if (!$lineArray) {
$result[0] = false;
$result[2] .= "Error in <strong>line ".$lineNumber."</strong>: can not split the string (".$lineString.")<br />";
}
$offset = 0;
while (isset ($regexps[$offset])) { // as long as there are regular expressions set hold them against the next field, if field count doesn't match --> false
$field = preg_match ($regexps[$offset], $lineArray[$offset]);
$offset++;
if (!$field | $field == "0") { //if regular expression didn't match or preg_match fails/dies
$result[0] = false;
$result[2] .= "Error in <strong>line ".$lineNumber.", field ".$offset."</strong>: no match with regular expression (".$lineArray[$offset-1].")<br />";
}
}
if (isset ($lineArray[$offset])) { //If there are more line's than regular expressions
$result[0] = false;
$result[2] .= "Error in <strong>line ".$lineNumber."</strong>: to many fields (".$lineString.")<br />";
}
}
return $result;
}
if (isset ($_POST['submit'])) {
$hoofdgroepen = $_POST ['hoofdgroepen'];
$regexps[0] = "/^[1-9]{1}[0-9]{0,3}$/";
$regexps[1] = "/^[a-zA-Z0-9.,()\/ ]{1,50}$/";
$regexps[2] = "/^[1-9]{1}[0-9]{0,3}$/";
$result = validCsv ($hoofdgroepen, $regexps);
echo "True/False: ".$result[0]."<br />";
echo "Number of lines: ".$result[1]."<br />";
echo "Errors: <br />".$result[2]."<br />";
}
?>
function validCsv ($csv, $regexps) {
$data = nl2br ($csv); //nl2br
$numberOfLines = substr_count($data, "<br />"); //Count occurances of <br />
$result[0] = true;
$result[1] = $numberOfLines;
$result[2] = "";
$lineNumber = 0;
while ($lineNumber < $numberOfLines) {
$lineNumber++;
list ($lineString, $data) = explode ("<br />", $data, 2); //First line in $lineString, rest in $data
$lineArray = str_getcsv ($lineString, ","); // split values of $lineString in array in $lineArray
if (!$lineArray) {
$result[0] = false;
$result[2] .= "Error in <strong>line ".$lineNumber."</strong>: can not split the string (".$lineString.")<br />";
}
$offset = 0;
while (isset ($regexps[$offset])) { // as long as there are regular expressions set hold them against the next field, if field count doesn't match --> false
$field = preg_match ($regexps[$offset], $lineArray[$offset]);
$offset++;
if (!$field | $field == "0") { //if regular expression didn't match or preg_match fails/dies
$result[0] = false;
$result[2] .= "Error in <strong>line ".$lineNumber.", field ".$offset."</strong>: no match with regular expression (".$lineArray[$offset-1].")<br />";
}
}
if (isset ($lineArray[$offset])) { //If there are more line's than regular expressions
$result[0] = false;
$result[2] .= "Error in <strong>line ".$lineNumber."</strong>: to many fields (".$lineString.")<br />";
}
}
return $result;
}
if (isset ($_POST['submit'])) {
$hoofdgroepen = $_POST ['hoofdgroepen'];
$regexps[0] = "/^[1-9]{1}[0-9]{0,3}$/";
$regexps[1] = "/^[a-zA-Z0-9.,()\/ ]{1,50}$/";
$regexps[2] = "/^[1-9]{1}[0-9]{0,3}$/";
$result = validCsv ($hoofdgroepen, $regexps);
echo "True/False: ".$result[0]."<br />";
echo "Number of lines: ".$result[1]."<br />";
echo "Errors: <br />".$result[2]."<br />";
}
?>
Ik heb geen idee wat er hier fout gaat, op mijn computer werkt het perfect...
Ik heb hier php 5.3.0, de server heeft php 5.2.6
Ik hoop dat iemand mij verder kan helpen
Alvast bedankt
Edit:
Ik heb het probleem gevonden, str_getcsv is een functie die pas bestaat sinds PHP 5 >= 5.3.0, hoe los ik dit op?
Gewijzigd op 15/06/2010 10:11:48 door Hans Vereyken
http://nl3.php.net/manual/en/function.str-getcsv.php#98088
http://nl3.php.net/manual/en/function.str-getcsv.php#94022
http://nl3.php.net/manual/en/function.str-getcsv.php#91170
http://nl3.php.net/manual/en/function.str-getcsv.php#89619
http://nl3.php.net/manual/en/function.str-getcsv.php#88773
Naja, zie de comments op php.net.
http://nl3.php.net/manual/en/function.str-getcsv.php#94022
http://nl3.php.net/manual/en/function.str-getcsv.php#91170
http://nl3.php.net/manual/en/function.str-getcsv.php#89619
http://nl3.php.net/manual/en/function.str-getcsv.php#88773
Naja, zie de comments op php.net.
Gewijzigd op 15/06/2010 13:08:53 door Afra ca
Ik heb alle linkjes bekeken, ik maar zoeken, het stond gewoon onder mijn neus. De eerste link is de beste, maar veel te uitgebreid, ik heb er dit van gemaakt, dat is genoeg voor wat ik nodig heb:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
if (!function_exists('str_getcsv')) {
function str_getcsv ($input) {
$input = str_replace (array("\r", "\r\n", "\n"), "", $input);
$input = $input.",";
$offset = 0;
while ($input != "") {
if (substr ($input, 0, 1) == "\"") {
list ($field, $input) = explode ("\",", substr ($input, 1), 2);
$return[$offset] = $field;
} else {
list ($field, $input) = explode (",", $input, 2);
$return[$offset] = $field;
}
$offset++;
}
return $return;
}
}
?>
if (!function_exists('str_getcsv')) {
function str_getcsv ($input) {
$input = str_replace (array("\r", "\r\n", "\n"), "", $input);
$input = $input.",";
$offset = 0;
while ($input != "") {
if (substr ($input, 0, 1) == "\"") {
list ($field, $input) = explode ("\",", substr ($input, 1), 2);
$return[$offset] = $field;
} else {
list ($field, $input) = explode (",", $input, 2);
$return[$offset] = $field;
}
$offset++;
}
return $return;
}
}
?>
Het is zeker geen volwaardig alternatief voor str_getcsv, maar zoals gezegd: voor mij is het voldoende.
@Afra ca
Ik denk niet dat dit probleem van toepassing was, maar zeker het lezen waard, danku!
Gewijzigd op 15/06/2010 21:43:13 door Hans Vereyken