utf om data in mysql in te voeren werkt niet
Ik gebruik de class: http://gasparesganga.com/labs/php-shapefile/#examples
voor in importeren van een shp bestand in mysql.
Ik krijg:
Quote:
Aïn Defla
Zo komt hij in de database.
Ik heb bij de database en het tabel erin het volgende gedaan
Code (php)
1
2
2
ALTER DATABASE databasename CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
In het PHP script heb ik ook dit gedaan:
Code (php)
1
2
3
2
3
header("Content-Type: text/html; charset=UTF-8");
mysqli_query($DBD->conn(),"SET NAMES 'utf8'");
mysqli_query($DBD->conn(),'SET CHARACTER SET utf8');
mysqli_query($DBD->conn(),"SET NAMES 'utf8'");
mysqli_query($DBD->conn(),'SET CHARACTER SET utf8');
Maar nee hoor hij blijft de tekens niet opslaan.
Het komt van een geojson bestand. Als ik deze open in kladblok staat daar ook in:
Aïn Defl
Wat kan hier aan de hand zijn?
Gewijzigd op 21/03/2017 22:24:45 door Daniel van Seggelen
Is dat tooltje ook op de hoogte van het feit dat het om unicode gaat?
Je haalt het eerst op en vervolgens gaat het naar Kladblok. Volgens mij blinkt Kladblok nu niet direct uit in dat soort dingen.
http://www.gadm.org/
Ik bekijk de data zoals het hier staat: http://gasparesganga.com/labs/php-shapefile/#examples
in kladblok bekeek ik het alleen maar om te kijken wat voor encoding het kan zijn.
Ik maak in mijn php script duidelijk (denk ik) dat het om utf-8 gaat. Maar dit werkt zo dus niet.
dit is mijn script:
<pre></pre>
Wanneer ik hem naar iso-8859-1 zet,
werken bepaalde tekens wel, maar heb nog niet alles kunnen testen
Even wat details, ik gebruik de shp files van: Ik bekijk de data zoals het hier staat: http://gasparesganga.com/labs/php-shapefile/#examples
in kladblok bekeek ik het alleen maar om te kijken wat voor encoding het kan zijn.
Ik maak in mijn php script duidelijk (denk ik) dat het om utf-8 gaat. Maar dit werkt zo dus niet.
dit is mijn script:
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
46
47
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
ini_set('max_execution_time', 8000);
ini_set('memory_limit', '-1');
include ("config.php");
include (DOC_ROOT."class/class.php");
$DBD = new DBD();
header('Content-Type: application/json; Charset=UTF-8');
mysqli_query($DBD->conn(),"SET NAMES 'utf8mb4_unicode_ci'");
mysqli_query($DBD->conn(),'SET CHARACTER SET utf8mb4_unicode_ci');
ini_set('display_errors',1);
error_reporting(E_ALL);
// Register autoloader
require_once(DOC_ROOT.'shp/php-shapefile-2.2.0/src/ShapeFileAutoloader.php');
\ShapeFile\ShapeFileAutoloader::register();
// Import classes
use \ShapeFile\ShapeFile;
use \ShapeFile\ShapeFileException;
try {
// Open shapefile
$ShapeFile = new ShapeFile(DOC_ROOT.'shp/files/gadm28_adm2.shp');
// Read all the records
while ($record = $ShapeFile->getRecord(ShapeFile::GEOMETRY_BOTH)) {
if ($record['dbf']['_deleted']) continue;
// Geometry
// echo $record['shp']['wkt'];
$wkt = mysqli_real_escape_string($DBD->conn(),$record['shp']['wkt']);
// DBF Data
// echo $record['dbf']['ISO'].'<br/;
$reg1 = mysqli_real_escape_string($DBD->conn(),$record['dbf']['NAME_0']);
$reg2 = mysqli_real_escape_string($DBD->conn(),$record['dbf']['NAME_1']);
$reg3 = mysqli_real_escape_string($DBD->conn(),$record['dbf']['NAME_2']);
$reg1 = iconv("UTF-8", "ISO-8859-1", $reg1);
$reg2 = iconv("UTF-8", "ISO-8859-1", $reg2);
$reg3 = iconv("UTF-8", "ISO-8859-1", $reg3);
$reg1url = strtolower($DBD->normalize($reg1));
$reg2url = strtolower($DBD->normalize($reg2));
$reg3url = strtolower($DBD->normalize($reg3));
?>
ini_set('memory_limit', '-1');
include ("config.php");
include (DOC_ROOT."class/class.php");
$DBD = new DBD();
header('Content-Type: application/json; Charset=UTF-8');
mysqli_query($DBD->conn(),"SET NAMES 'utf8mb4_unicode_ci'");
mysqli_query($DBD->conn(),'SET CHARACTER SET utf8mb4_unicode_ci');
ini_set('display_errors',1);
error_reporting(E_ALL);
// Register autoloader
require_once(DOC_ROOT.'shp/php-shapefile-2.2.0/src/ShapeFileAutoloader.php');
\ShapeFile\ShapeFileAutoloader::register();
// Import classes
use \ShapeFile\ShapeFile;
use \ShapeFile\ShapeFileException;
try {
// Open shapefile
$ShapeFile = new ShapeFile(DOC_ROOT.'shp/files/gadm28_adm2.shp');
// Read all the records
while ($record = $ShapeFile->getRecord(ShapeFile::GEOMETRY_BOTH)) {
if ($record['dbf']['_deleted']) continue;
// Geometry
// echo $record['shp']['wkt'];
$wkt = mysqli_real_escape_string($DBD->conn(),$record['shp']['wkt']);
// DBF Data
// echo $record['dbf']['ISO'].'<br/;
$reg1 = mysqli_real_escape_string($DBD->conn(),$record['dbf']['NAME_0']);
$reg2 = mysqli_real_escape_string($DBD->conn(),$record['dbf']['NAME_1']);
$reg3 = mysqli_real_escape_string($DBD->conn(),$record['dbf']['NAME_2']);
$reg1 = iconv("UTF-8", "ISO-8859-1", $reg1);
$reg2 = iconv("UTF-8", "ISO-8859-1", $reg2);
$reg3 = iconv("UTF-8", "ISO-8859-1", $reg3);
$reg1url = strtolower($DBD->normalize($reg1));
$reg2url = strtolower($DBD->normalize($reg2));
$reg3url = strtolower($DBD->normalize($reg3));
?>
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
$r = mysqli_query($DBD->conn(),"insert into adm3 (iso,SHAPE,Region1,Region2,Region3,Region1Url,Region2Url,Region3Url) values ('".$record['dbf']['ISO']."',GeomFromText('".$wkt."'),'".$reg1."','".$reg2."','".$reg3."','".$reg1url."','".$reg2url."','".$reg3url."')") or die (mysqli_error($DBD->conn()));
//echo "insert into adm3 (iso,SHAPE,Region1,Region2,Region3) values ('".$record['dbf']['ISO']."',GeomFromText('".$wkt."'),'".$reg1."','".$reg2."','".$reg3."')";
}
} catch (ShapeFileException $e) {
// Print detailed error information
exit('Error '.$e->getCode().' ('.$e->getErrorType().'): '.$e->getMessage());
}
$r = mysqli_query($DBD->conn(),"insert into adm3 (iso,SHAPE,Region1,Region2,Region3,Region1Url,Region2Url,Region3Url) values ('".$record['dbf']['ISO']."',GeomFromText('".$wkt."'),'".$reg1."','".$reg2."','".$reg3."','".$reg1url."','".$reg2url."','".$reg3url."')") or die (mysqli_error($DBD->conn()));
//echo "insert into adm3 (iso,SHAPE,Region1,Region2,Region3) values ('".$record['dbf']['ISO']."',GeomFromText('".$wkt."'),'".$reg1."','".$reg2."','".$reg3."')";
}
} catch (ShapeFileException $e) {
// Print detailed error information
exit('Error '.$e->getCode().' ('.$e->getErrorType().'): '.$e->getMessage());
}
Wanneer ik hem naar iso-8859-1 zet,
werken bepaalde tekens wel, maar heb nog niet alles kunnen testen
Gewijzigd op 21/03/2017 22:41:17 door Daniel van Seggelen
Alleen in kladblok?
Het probleem komt wanneer ik hem importeer in de mysql database
Dus daarom mijn vraag: waarom ben jij van mening dat er een probleem IS?
Kennelijk kijk jij op de een of andere manier in de database. De vraag is: HOE / WAARMEE?
En de vervolgvraag is dan of die methode om kan gaan met unicode, danwel unicode verwacht.
Als je ergens 2 (rare) tekens ziet op een plek waar je eigenlijk 1 teken met een accent verwacht, dan is dat een signaal dat een multibyte (unicode) teken wordt weergegeven door een programma dat single byte karakters verwacht. (en dus niet om kan/wenst te gaan met unicode).
Ik kijk met phpmyadmin in de database.
Mar zoals ik zei als ik hem naar iso-8859-1 zet, en dan invoer dan komt het wel goed in de database met UTF-8 terecht :)
Hoe werkt "DBD" precies?
En het instellen van de character encoding (hierna CE) waarmee je spreekt met je database via SET NAMES / CHARACTER SET wordt afgeraden. Hiervoor is set_charset().
Ik denk dat een van de volgende dingen aan de hand kan zijn:
- de CE van je brondata is niet van de CE die deze zegt te zijn, hierdoor vertaal je dingen fout
- het gaat fout bij het wegschrijven omdat de CE op de verkeerde manier is ingesteld
- het gaat fout bij het uitlezen omdat je daar wellicht de CE wel op de goede manier hebt ingesteld, maar de data zat fout in de database; omdat de connectie van de voorgeschreven CE is (congruent met tabeldefinities), wordt de foute data niet terugvertaald, hierdoor wordt de foute opslag ook niet teruggedraaid
- het gaat fout bij het weergeven omdat je in je meta-tag en/of je PHP-header niet de juiste CE opgeeft of dat deze ontbreekt
ALTER TABLE werkt uiteraard alleen als de data die in de database zat ook daadwerkelijk van de voorgeschreven (oude) CE was, anders wordt de data naar alle waarschijnlijkheid verkeerd vertaald naar de nieuwe CE.
Mijn vermoeden, uitgaande van "Aïn Defla": ergens is niet ingesteld dat je utf8 gebruikt, dus de data wordt alsnog vertaald naar utf8. Voer maar eens een utf8_decode() uit op "Aïn Defla". Dit kan direct te maken hebben met het feit dat je niet op de goede manier een CE instelt bij het maken van de verbinding.
Dit heeft tevens implicaties voor de data die al in je database zit op het moment dat je deze repareert door gebruikmaking van set_charset()! Alle data in je database van voor de reparatie met gebruikmaking van set_charset() is waarschijnlijk 1x teveel utf8-geëncodeerd. Dit ging voorheen goed omdat de database er van uitging dat je latin1-data wenste te ontvangen, daarom werd bij het opvragen van data deze terugvertaald van utf8 naar "latin1" (maar je wilde eigenlijk utf8).
Gewijzigd op 22/03/2017 16:25:54 door Thomas van den Heuvel
En volgens mij gaat die er (default) niet vanuit dat er met unicode gewerkt wordt.
Dus dat 1 tool de waarden fout weergeeft, wil niet zeggen dat er ook echt een probleem is.
Zorg dat je script om de data goed is opgezet om met utf te werken. En maak ook een vergelijkbaar script dat de data ophaalt.
Beoordeel dan of het goed ging.
en gebruik niet een of andere willekeurige tool om die al de waarheid aan te houden
Ivo P op 22/03/2017 17:35:03:
bedenk ook dat phpmyadmin ook maar een php-script is.
En volgens mij gaat die er (default) niet vanuit dat er met unicode gewerkt wordt.
En volgens mij gaat die er (default) niet vanuit dat er met unicode gewerkt wordt.
Dit maakt denk ik niet uit, zolang je maar consequent één character encoding (hierna weer CE te noemen) aanhoudt. Aangezien phpMyAdmin een pakket is denk ik dat dat intern wel snor zit.
set_charset() vormt in feite een contract tussen de applicatie en de database. Hierin worden (ten minste) twee dingen overeengekomen:
1. de applicatie levert data in de overeengekomen CE aan
2. de database retourneert data in de overeengekomen CE
In feite zeg je "dit is de CE die ik wens te gebruiken / gebruik in mijn applicatie".
De CE van de database/tabellen kan best verschillen van de CE die je gebruikt in je applicatie. MySQL zorgt onder water voor vertalingen. Maar omdat je niet expliciet instelt wat voor CE je gebruikt in je applicatie gaat MySQL mogelijk van een verkeerde default (latin1?) uit. Hiermee breek je (mogelijk onbewust) je eerder gemaakte belofte.
Dit is dan wat er achtereenvolgens gebeurt bij wegschrijven van UTF-8 (utf8) data:
MySQL gaat uit van latin1.
MySQL ontvangt (UTF-8) data en ziet dat deze in een utf8-tabel moet worden weggeschreven.
MySQL encodeert dan (nogmaals) de data naar utf8.
En het ophalen van data:
MySQL gaat uit van latin1.
MySQL ziet dat de data in utf8 tabellen zit.
De applicatie vraagt (impliciet) om latin1 dus MySQL vertaalt de data eenmalig van utf8 naar latin1.
Daarom lijkt het aan de buitenkant allemaal goed te gaan omdat MySQL onder water (overbodige) vertalingen uitvoert die de zaak weer recht lijken te breien.
Het gevaar bij het niet expliciet instellen van een CE is dus dat de data mogelijk dubbel ge-encodeerd wordt weggeschreven. Dit komt dan pas naar buiten bij een export of wanneer je je connectie repareert. Maar dan heb je dus nog steeds stront want de data die al in je database zat wordt dan op de verkeerde manier uitgelezen en is in zekere zin nog steeds "corrupt".
Dit alles is nogal moeilijk over te brengen maar het helpt al enorm veel als er enig bewustzijn wordt gecreëerd van het bestaan van character encoderingen en hoe je hier fatsoenlijk mee om zou moeten gaan... Misschien is de beste remedie nog altijd dat je tot je
Gewijzigd op 23/03/2017 02:01:37 door Thomas van den Heuvel