graden teken DEC 176 breekt tekst af bij wegschrijven records
bv. "het is vandaag 10° en mooi weer"
indien ik dit bijwerkt of wegschrijft in de MYSQL database krijg ik het volgende te zien
"het is vandaag 10"
Alles achter de 10 wordt niet weggeschreven
wat kan daar de oorzaak van zijn?
Groet Jonet
Kan je jouw relevante code geven?
Welke character encoding gebruik je:
- in het HTML-document waarin je dit weergeeft?
- bij het maken van de database-connectie? (m.b.v. set_charset)
- verder is het handig, maar niet per se noodzakelijk, dat al deze character encoderingen min of meer gelijk zijn (dus bijvoorbeeld UTF-8 in het document, en "utf8" bij het maken van een database-connectie)
Of mogelijk heeft de kolom in de database-tabel te weinig plek voor deze tekst.
Hoe luidt de definitie van de databasetabel/-kolom?
Of misschien gebruik je een afwijkende character encoding bij het weergeven/escapen van deze output? Maar dan zou ik eigenlijk verwachten dat je geen output te zien krijgt.
Het blijft inderdaad koffiedik kijken zonder enige relevante code.
code ziet er zo uit
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
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
<?php
$sleutel = "2357981";
$weer = "vandaag 23° en mooie zonnige dag";
$mysql_table = "weer";
# Database openen om DB aan te spreken.
$db = new mysqli($mysql_server, $mysql_username, $mysql_password);
$db->select_db($mysql_database);
# Correcte weergave vreemde karakters in unicode
$db->set_charset("utf8");
$query = ("INSERT INTO $mysql_table (sleutel, weer) VALUES ('$sleutel', $weer);");
$results = $db->query($query);
// resultaat : "vandaag 23" ipv "vandaag 23° en mooie zonnige dag"
if($results === false) {
echo $db->error . "<br>"; # fouten laten zien in browser
$QueryError = true;
}
else {
# Insert is gelukt. gegevens laten zien in browser.
echo "<tr><td>$sleutel</td><td>$weer</td></tr><br>";
}
# Sluiten database
$db->close();
?>
$sleutel = "2357981";
$weer = "vandaag 23° en mooie zonnige dag";
$mysql_table = "weer";
# Database openen om DB aan te spreken.
$db = new mysqli($mysql_server, $mysql_username, $mysql_password);
$db->select_db($mysql_database);
# Correcte weergave vreemde karakters in unicode
$db->set_charset("utf8");
$query = ("INSERT INTO $mysql_table (sleutel, weer) VALUES ('$sleutel', $weer);");
$results = $db->query($query);
// resultaat : "vandaag 23" ipv "vandaag 23° en mooie zonnige dag"
if($results === false) {
echo $db->error . "<br>"; # fouten laten zien in browser
$QueryError = true;
}
else {
# Insert is gelukt. gegevens laten zien in browser.
echo "<tr><td>$sleutel</td><td>$weer</td></tr><br>";
}
# Sluiten database
$db->close();
?>
Ik raad aan om het eens te escapen:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
$query = "INSERT INTO $mysql_table (sleutel, weer)
VALUES (
'".$db->real_escape_string($sleutel)."',
'".$db->real_escape_string($weer)."'
)
";
VALUES (
'".$db->real_escape_string($sleutel)."',
'".$db->real_escape_string($weer)."'
)
";
Gewijzigd op 27/01/2020 19:32:17 door - Ariën -
Dat escapen is een zeeeeer goed gewoonte, maar gaat je probleem niet oplossen.
Wel als hij een ' zou gebruiken in zijn string. Dan stopt de query ermee...
Als die $sleutel bijvoorbeeld het resultaat is van $x * $y (dus altijd numeriek), en het veld `weer` is ook een numeric veld, dan heeft escaping ook totaal geen toegevoegde waarde.
Maar dat is hier al 100k keer voorbij gekomen, dus leek me niet nodig om hier nogmaals te herkauwen, omdat het (vermoedelijk - vooruit dan, hou ik toch een slag om de arm) niks mee te maken heeft.
Escapen (in combinatie met quotes) is altijd een goed idee, maar dat is naar alle waarschijnlijkheid niet het probleem hier.
Dus, mogelijke oplossing: sla het PHP-bestand op met UTF-8 encodering. De meeste editors (en volgens mij kon Notepad dit zelfs) bieden deze mogelijkheid wel, en kun je zelfs per bestandstype vastleggen wat de encodering standaard zou moeten zijn, zodat je dit ook nooit meer fout doet :).
Gewijzigd op 28/01/2020 02:03:25 door Thomas van den Heuvel
Hoogstens vraagtekens of vraagtekens in ruitjes.
Gewijzigd op 28/01/2020 00:12:52 door - Ariën -
Misschien is er te weinig ruimte in de kolom - hoe luidt de tabeldefinitie?
"vandaag 23" is precies tien karakters.
Normaal gesproken komt deze tekst ook uit een formulier of wat dan ook, en is het geen statische tekst in een PHP-bestand lijkt mij?
Gewijzigd op 28/01/2020 16:17:02 door Thomas van den Heuvel
bedankt voor het meedenken.
probleem treed niet op als ik via phpmyadmin upload
dus ben ik verder gaan zoeken
als ik de volgende regel op remark zet doet die het wel goed verwerken
//$db->set_charset("utf8");
ik ben nog verder aan het testen geweest.
en als ik de strings eerst
$weer = utf8_encode($weer);
en daarna de query uitvoert upload die de gehele string incl ° (graden )
hierbij kan de remark weer weggehaald worden bij $db->set_charset("utf8");
topic is dus opgelost.
Groetjes jonet
Fijn dat het directe probleem is opgelost... maar ik voel mij toch genoodzaakt te benadrukken dat dit waarschijnlijk geen optimale oplossing is. Ik zal proberen uit te leggen waarom.
De reden dat het bovenstaande werkt is in zekere zin een (toevallige) samenloop van omstandigheden. Op het moment dat je dingen programmeert is het verstandig om zo min mogelijk aan het toeval over te laten. Daartoe is het meestal handig om zoveel mogelijk dingen expliciet in te stellen. Zo ook de character encoding van je database-connectie.
De bovenstaande aanpak mag dan werken, maar de character encoding van de betreffende tekst flippert al dan niet onder water een aantal keren heen en weer tussen UTF-8/utf8 en een andere encodering, en de enige reden dat dit goed gaat is omdat de default character encoding die MySQL gebruikt toevallig overeenkomt / compatibel is met die andere encodering.
Mocht een van de twee veranderen (bijvoorbeeld door een verhuizing naar een andere server, een upgrade van MySQL of een verandering in de aanlevering van de informatie, of misschien simpelweg omdat je dit alles op een andere omgeving ontwikkelt dan waar deze code daadwerkelijk wordt gebruikt) dan breekt deze aanpak opnieuw. Het is beter om op zoveel mogelijk plekken expliciet voor te schrijven in welke vorm informatie aangeleverd moet worden.
Mijn vraag is dan ook: hoe komt deze informatie normaliter in de database terecht? Is iemand echt de inhoud van een tekstbestand aan het aanpassen, of gebruik je een formulier, of iets anders (hierboven heb je het over PHPMyAdmin)?
Op het moment dat dat duidelijk is (hoe informatie wordt aangeleverd) kunnen we (verder) kijken hoe je dit op een fatsoenlijke(re) manier in de database krijgt, zonder ook maar één keer een vertaalslag tussen encoderingen te maken. Dit laatste biedt geen enkele ruimte voor de "ruis" die je mogelijk bij dit soort vertalingen ondervindt, zoals je beschreef in je oorspronkelijke vraagstuk.
Voorkomen lijkt mij in dit geval beter dan (tijdelijk) genezen.
Gewijzigd op 29/01/2020 02:28:14 door Thomas van den Heuvel
sorry voor de late reactie
Het wordt aangestuurd op een lokale pc met een programma in C++ builder van borland.
Het tekenset wat daar wordt gebruikt is dan windows 1252
Dit wordt met een post verzonden naar het script op de server.
de coalitie staat van de mysql database ingesteld op utf8_general_ci.
Okay, dus je bronmateriaal is Windows-1252 geëncodeerd. Dit zou equivalent (of in ieder geval in grote lijnen compatibel) moeten zijn met latin1.
Voor het begrip is het volgende heel belangrijk: je moet set_charset() zien als het contract tussen jouw code en de database. Dit contract heeft twee belangrijke speerpunten:
- jij moet er zorg voor dragen dat de informatie die jij aan MySQL aanlevert van de voorgeschreven encodering is
- MySQL doet haar best om de informatie (uit de database) terug te geven in de voorgeschreven encodering
En het allerbelangrijkste hierbij is de realisatie dat MySQL hiertoe, indien nodig, en naar beste vermogen, vertalingen tussen encoderingen uitvoert. De encodering waarmee je werkt en de encodering waarin data staat opgeslagen mogen dus best van elkaar verschillen.
Voor het wegschrijven van Windows-1252 informatie houdt dit dus (theoretisch :)) in dat je voor het wegschrijf-script latin1 gebruikt. Het lijkt mij nog steeds belangrijk om dit expliciet in te stellen middels set_charset(). MySQL ziet vervolgens "Hee, ik krijg hier latin1-data binnen, maar ik moet dit wegschrijven naar een utf8-tabel/kolom." en maakt dan automatisch -en naar beste vermogen- een vertaalslag naar utf8 conform het contract.
NB: als dit niet werkt en er toch karakters verdwijnen dan zul je dieper moeten duiken in de precieze verschillen tussen de encoderingen of een soort van workaround moeten verzinnen.
En als je vervolgens deze informatie weer wilt weergeven, bijvoorbeeld op een HTML-pagina met UTF-8 encodering, dan stel je dus set_charset() in op utf8 (en daarnaast zou het HTML-document een meta-tag of PHP header moeten bevatten waaruit blijkt welke encodering deze gebruikt). Als je dan data uit je database trekt dan ziet MySQL "Hee, ik krijg hier het verzoek om informatie te retourneren in utf8, en de informatie in kwestie is al utf8, dus ik hoef verder niets te vertalen." en retourneert de informatie (rechtstreeks) in utf8 conform het contract.
Een collation is de manier waarop karakters worden vergeleken (wanneer zijn symbolen gelijk) en gesorteerd (welke symbolenreeks komt alfabetisch voor een andere symbolenreeks bij het sorteren op een tabelkolom) en heeft niet echt invloed op encodering of de bijbehorende problematiek. Tegelijkertijd hoef je niet te verwachten dat de collatie voorspelbaar werkt indien de data in je database verkeerd geëncodeerd is.
Ik ga er naar kijken of dat inderdaad ook functioneert.
kom er later op terug of het inderdaad lukt