; vervangen door tab nav Fatal error: mysqli_set_local_infile_handler

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Bas van de Ven

Bas van de Ven

11/04/2015 17:33:18
Quote Anchor link
Sinds kort ben ik lokaal overgegaan van usbwebserver 8.0 naar 8.6 (php versie 5.4.17)
Binnen 8.0 werkt de functie mysqli_set_local_infile_handler() nog steeds goed.

Binnen hetzelfde script krijg ik nu in 8.6 de foutmeding 'Fatal error: Call to undefined function mysqli_set_local_infile_handler() in ...'.
Is dit een instelling binnen php.ini misschien?

Mijn code is gebasseerd op http://php.net/manual/en/mysqli.set-local-infile-handler.php.

Met de oplossing op http://board.phpbuilder.com/showthread.php?10375297-RESOLVED-LOAD-DATA-INFILE-error wordt er nagenoeg een lege tabel ingelezen. Veel velden bevatten NULL-waarden.

Weet iemand de reden en een oplossing ?

Mijn code :
<code>
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
include "url.php";

$stream = $end_file_reader; //Gedeclareerd in InlezenReader.php
$buffer = $file_r; //Gedeclareerd in InlezenReader.php
$buflen = 51000;
$errmsg = "Er is iets goed fout !";


$truncate = mysqli_query($db,"TRUNCATE TABLE ".mysqli_real_escape_string($db,$lidId)."_impReader") or die (mysqli_error($db));
 
  function
callme($stream, &$buffer, $buflen, &$errmsg)
  {

    $buffer = fgets($stream);

    //echo $buffer;

    // convert to upper case and replace "," delimiter with [TAB]

    $buffer = strtoupper(str_replace(";", "\t", $buffer));

    return strlen($buffer);
  }



 // echo "Input:<br/>";

  mysqli_set_local_infile_handler($db, "callme");
  mysqli_query($db, "LOAD DATA LOCAL INFILE '". $stream. "' INTO TABLE ".mysqli_real_escape_string($db,$lidId)."_impReader") or die (mysqli_error($db));
  mysqli_set_local_infile_default($db);
?>

</code>

Toevoeging op 12/04/2015 12:32:29:

Met de oplossing op http://board.phpbuilder.com/showthread.php?10375297-RESOLVED-LOAD-DATA-INFILE-error ben ik wel verder gekomen. Ik wil een txt-bestand inlezen. Als de waarden in dit bestand gescheiden zijn door een tab dan gaat het goed. In het bestand dat ik krijg aangeleverd worden de waarde gescheiden door een ; .

Mijn code zie er nu zo uit
<code>
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
$stream
= $end_file_reader; //Bestandsnaam bijv. reader_1 . Gedeclareerd in InlezenReader.php

    mysqli_query($db,"TRUNCATE TABLE ".mysqli_real_escape_string($db,$lidId)."_impReader") or die (mysqli_error($db));
 
  mysqli_query($db, "LOAD DATA LOCAL INFILE '". $stream. "' INTO TABLE ".mysqli_real_escape_string($db,$lidId)."_impReader TERMINATED BY ';' ") or die (mysqli_error($db));
?>

</code>

Dit levert de volgende fout op : ' You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TERMINATED BY ';'' at line 1 '. Mogelijk omdat het in mijn geval geen csv- maar een txt-bestand is.

Weet iemand hoe ik in een txt-bestand de ; kan vervangen door een tab ? Eventueel in combinatie met de functie LOAD DATA LOCAL INFILE.
Ik heb ook al zitten vogelen met
<code>
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
 $file_bewerk
= fopen ($file_r."/".$end_file_reader, "w");
while (!feof ($file_bewerk)) {
    $lines = fgets($file_bewerk, 4096);
    str_replace(";", "\t", $lines);
    echo $lines;
}

fclose ($file_bewerk);
?>


Er moeten zo'n 46 ;'s worden vervangen.
Hierbij is de melding ' Fatal error: Maximum execution time of 30 seconds exceeded '
Gewijzigd op 12/04/2015 13:14:11 door Bas van de Ven
 
PHP hulp

PHP hulp

26/04/2024 12:40:22
 
Marthijn Buijs

Marthijn Buijs

12/04/2015 13:58:31
Quote Anchor link
Bas van de Ven op 11/04/2015 17:33:18:
Hierbij is de melding ' Fatal error: Maximum execution time of 30 seconds exceeded '


Dit kan je voorkomen door het volgende bovenaan je php script te plaatsen.
(de '0' betekend oneindig)

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
set_time_limit(0);
 
- SanThe -

- SanThe -

12/04/2015 14:02:52
Quote Anchor link
Maarten Buis op 12/04/2015 13:58:31:
Dit kan je voorkomen door het volgende bovenaan je php script te plaatsen.
(de '0' betekend oneindig)
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
set_time_limit(0);


En als ie nou in een eindeloze loop zit?
Vaak F5 doen.
Gaat vanzelf de server plat.
 
Marthijn Buijs

Marthijn Buijs

12/04/2015 14:05:34
Quote Anchor link
- SanThe - op 12/04/2015 14:02:52:
Maarten Buis op 12/04/2015 13:58:31:
Dit kan je voorkomen door het volgende bovenaan je php script te plaatsen.
(de '0' betekend oneindig)
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
set_time_limit(0);


En als ie nou in een eindeloze loop zit?
Vaak F5 doen.
Gaat vanzelf de server plat.


Maar in dit geval is het niet oneindig maar 46x
Dus moet gewoon kunnen toch?
 
- SanThe -

- SanThe -

12/04/2015 14:07:36
Quote Anchor link
Ik ben geen voorstander van op 0 zetten.
 
Bas van de Ven

Bas van de Ven

12/04/2015 15:11:16
Quote Anchor link
Bedankt voor de input. Echter ben ik meer benieuwd naar hoe ik in een txt-bestand de ; kan wijzigen naar een tab. Ik gaf enkel aan wat ik al had geprobeerd.
46 tekens zijn m.i. niet veel om de melding '... 30 seconds' te geven.
Iets doe ik dus niet goed, maar wat ?
Gewijzigd op 12/04/2015 15:20:55 door Bas van de Ven
 
Thomas van den Heuvel

Thomas van den Heuvel

12/04/2015 15:59:40
Quote Anchor link
@Bas: ik denk dat je te moeilijk redeneert. De LOAD DATA INFILE functionaliteit is heel erg flexibel, je hoeft zelf niet van die moeilijke omzettingen te gaan doen. Je zegt:
Quote:
Dit levert de volgende fout op : ' You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TERMINATED BY ';'' at line 1 '. Mogelijk omdat het in mijn geval geen csv- maar een txt-bestand is.

CSV is toch ook tekst? Ik denk dat wat er fout gaat precies in deze foutmelding staat omschreven: de syntax van deze aanroep is verkeerd. Je moet er namelijk bijvertellen wat er gescheiden wordt door een punt-komma: een kolom (field) of een rij (line).

De juiste syntax is dus waarschijnlijk:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
LOAD DATA LOCAL INFILE '/path/to/file.csv'
INTO TABLE table_name
FIELDS TERMINATED BY ';'

En als de CSV/TXT bestanden op het Windows platform zijn gegenereerd doe je er wellicht verstandig aan om ook
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
LINES TERMINATED BY '\r\n'

Toe te voegen.

Lees de LOAD DATA INFILE Syntax eens door.

Daarnaast nog een tip: maak afspraken over hoe (in welke vorm) men data moet aanleveren. Als je iets alleen (of makkelijker) correct kunt verwerken als er een bepaalde variant wordt gebruikt, dan mag je dit best verlangen van een externe partij. Daarbij kun je ze natuurlijk ook tegemoet komen door uit te leggen hoe zij deze data kunnen omzetten naar de gewenste variant.

EDIT: en als deze bestanden de regels van CSV volgen, dan moet je waarschijnlijk ook de eerste regel skippen, dit doe je dan weer met (zie documentatie):
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
IGNORE 1 LINES


EDIT2: Als de kolomdata zelf deze scheidingstekens bevatten, dan is het ook verstandig dat de kolommen zelf (altijd) zijn omvat door een karakter (meestal een dubbele quote ofzo).

Vergelijk
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
dit;is;een;kolom;test

met
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
"dit;is;een;kolom";"test"

Van het eerste geval kan een machine (en ik ook niet :)) niet afleiden dat dit twee kolommen betreft, en waar de scheiding precies ligt. De tweede variant is ondubbelzinnig.

Dit kun je weer regelen door
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
ENCLOSED BY '"'

toe te voegen aan je FIELDS-regel EN ervoor te zorgen / af te dwingen dat deze data zo wordt aangeleverd!

Wederom: zie de docs.
Gewijzigd op 12/04/2015 16:11:04 door Thomas van den Heuvel
 
Bas van de Ven

Bas van de Ven

12/04/2015 17:15:29
Quote Anchor link
Bedankt Thomas,
Met jou aanwijzingen heb ik het weer werkend gekregen. Ik was dus een heel eind.
De LINES TERMINATED BY '\r\n' heb ik voor de zekerheid ook maar toegevoegd. Zonder te kunnen testen wanneer het effect heeft. Ik baseer me dus enkel op jou toelichting.

Wat betreft het aanleveren van een txt-bestand. Hier heb ik met een partij afspraken over gemaakt. O.b.v. uniformiteit heb ik voor ; als scheidingsteken gekozen. Dit had ik nl. al eerder gebruikt.
Gewijzigd op 12/04/2015 17:16:02 door Bas van de Ven
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.