graden teken DEC 176 breekt tekst af bij wegschrijven records

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jonet L

Jonet L

27/01/2020 17:05:23
Quote Anchor link
hallo, ik wil een record wegschrijven met een zinnetje weer
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
 
PHP hulp

PHP hulp

28/02/2020 19:08:37
 
- Ariën -
Beheerder

- Ariën -

27/01/2020 17:07:41
Quote Anchor link
Kan je jouw relevante code geven?
 
Thomas van den Heuvel

Thomas van den Heuvel

27/01/2020 17:39:08
Quote Anchor link
Klinkt als een character encoding probleem.

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.
 
Jonet L

Jonet L

27/01/2020 19:20:39
Quote Anchor link
Ik ben niet zo heel goed thuis nog in werken met databases...

code ziet er zo uit


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
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();
                            
?>
 
- Ariën -
Beheerder

- Ariën -

27/01/2020 19:30:09
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
    $query = ("INSERT INTO $mysql_table (sleutel, weer) VALUES ('$sleutel', $weer);");


Ik raad aan om het eens te escapen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
    $query = "INSERT INTO $mysql_table (sleutel, weer)
        VALUES (
            '".$db->real_escape_string($sleutel)."',
            '".$db->real_escape_string($weer)."'
            )
            ";
Gewijzigd op 27/01/2020 19:32:17 door - Ariën -
 
Rob Doemaarwat

Rob Doemaarwat

27/01/2020 20:09:52
Quote Anchor link
En wat is de encoding van dat stukje PHP script (moet dus ook UTF8 - zonder BOM - zijn).

Dat escapen is een zeeeeer goed gewoonte, maar gaat je probleem niet oplossen.
 
- Ariën -
Beheerder

- Ariën -

27/01/2020 20:13:17
Quote Anchor link
Wel als hij een ' zou gebruiken in zijn string. Dan stopt de query ermee...
 
Rob Doemaarwat

Rob Doemaarwat

27/01/2020 22:29:03
Quote Anchor link
Ja, dan wel. Maar het probleem is nu dat alles na het gradenteken niet wordt opgeslagen, en daarmee heeft escaping niks van doen.

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.
 
Thomas van den Heuvel

Thomas van den Heuvel

27/01/2020 23:56:09
Quote Anchor link
Als het letterlijk een tekststring is in het PHP-bestand zelf, dan ligt het waarschijnlijk aan de manier waarop het bestand is opgeslagen. Als dit niet met een UTF-8 encodering gebeurt dan gaat dat graden-teken waarschijnlijk door de vleesmolen omdat je met set_charset() (tevens) aangeeft dat alle data die je aan de database aanlevert ook UTF-8 is (of zou moeten zijn). PHP is verder redelijk "doof" voor character encoderingen, deze is enkel geïnteresseerd in bytes.

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
 
- Ariën -
Beheerder

- Ariën -

28/01/2020 00:12:30
Quote Anchor link
Hm... ik heb overigens nog nooit afgebroken strings gezien door UTL-8 troubles?
Hoogstens vraagtekens of vraagtekens in ruitjes.
Gewijzigd op 28/01/2020 00:12:52 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

28/01/2020 02:14:45
Quote Anchor link
Wanneer je het PHP-bestand opslaat als ISO-whatever dan krijg je idd een ? in je database, en niet een afgebroken string.

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
 
Jonet L

Jonet L

28/01/2020 23:48:41
Quote Anchor link
aan allen
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
 
Thomas van den Heuvel

Thomas van den Heuvel

29/01/2020 00:13:33
Quote Anchor link
Beste 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
 
Jonet L

Jonet L

03/02/2020 10:23:09
Quote Anchor link
Beste Thomas,

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.
 
Thomas van den Heuvel

Thomas van den Heuvel

03/02/2020 16:26:56
Quote Anchor link
Aha, dus PHP handelt het wegschrijven af.

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.
 
Jonet L

Jonet L

04/02/2020 15:03:03
Quote Anchor link
ok, helder
Ik ga er naar kijken of dat inderdaad ook functioneert.
kom er later op terug of het inderdaad lukt
 



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.