probleem met htmlentities in php 5.6

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

J opla

j opla

08/11/2015 21:17:42
Quote Anchor link
Beste Mensen,

Ik probeer mijn website om te zetten van php 5.3 naar php 5.6. Nu kom ik een probleem tegen met htmlentities.

Uit een MySQL database worden gegevens gehaald. Als er vreemde tekens zoals een Duitse RingelS (ß) dan krijg in een lege $var als ik:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
<?    $var=htmlentities($data['titel']);     ?>
gebruik.

Als ik "htmlentities" weg laat dan krijg ik een "zwart wiebertje met een ?" (�) op de plaats van de ringels (ß).

De database staat in UTF-8, de site ook.

Wie weet de oplossing?

Al vast bedankt.

Toevoeging op 08/11/2015 21:40:34:

Aanvulling:
Met toevoeging van "ENT_IGNORE | ENT_HTML5" verdwijnen de speciale letters en is de $var dus niet leeg.

Toevoeging op 08/11/2015 21:45:39:

Aanvulling:
Als ik de flags "ENT_HTML5, "ISO-8859-1" toe voeg dan verschijnt de tekst wel goed, maar dat lijkt me vreemd omdat voilgens mij alles in UTF-8 zou moeten staan ...
Gewijzigd op 08/11/2015 21:30:42 door J opla
 
PHP hulp

PHP hulp

23/04/2024 09:31:09
 
Thomas van den Heuvel

Thomas van den Heuvel

08/11/2015 22:47:25
Quote Anchor link
Grote kans dat je data niet goed in je database zit, waarschijnlijk omdat er zoiets aan de hand is:
- je HTML document is UTF-8
- je database-tabellen en -kolommen zijn UTF-8
- je had/hebt geen charset geselecteerd bij het maken met een verbinding met je database d.m.v. een set_charset() functie, waardoor
- de DATA in je database NIET UTF-8 is

Deze problemen kwamen mogelijk niet eerder naar buiten omdat de default encoding van htmlentities() en htmlspecialchars() voor PHP 5.6 hoogstwaarschijnlijk ISO-8859-1 was (daarbij is het natuurlijk altijd beter om expliciet aan te geven welke encoding je gebruikt).

Long story short: de (tekstuele) data in je database is naar alle waarschijnlijkheid semi-corrupt en je zult een conversie moeten uitvoeren om deze te repareren.

De eerste stap/stappen die je zult moeten uitvoeren zijn:
- zorgen dat overal je character encoderingen in de pas lopen (HTML document, database connectie, tabel- en kolomdefinities en last but not least de DATA in je database, waarvoor je)
- een analyse uit zult moeten voeren wat er precies aan de hand is met je data zodat je deze daarna eenmalig kunt converteren

Deze twee stappen (gelijkschakeling+conversie) zul je tegelijkertijd moeten uitvoeren omdat je anders weer soortgelijke problemen krijgt als je nieuwe data gaat invoeren of bestaande data gaat aanpassen.

Maar allereerst moet je eigenlijk boven water krijgen wat er PRECIES aan de hand is met je database-data.

EDIT: in een ideale situatie lopen alle character encoderingen gelijk. Om na te gaan of hier iets niet in de haak zit zou je dus kunnen controleren of er onderweg conversies vertalingen tussen character encoderingen worden uitgevoerd. Dit kun je controleren door aan de MySQL-kant te kijken naar de HEX()-waarde van een tekst met exotische karakters, en deze zelfde tekstkolom aan de PHP-kant door de bin2hex() functie te halen. Als de HEX() representatie verschilt van die van de bin2hex() variant (afgezien van uppercase/lowercase) wil dat zeggen dat MySQL het nodig vond om de data te vertalen om deze geschikt te maken voor weergave (en dat dus de character encoderingen niet goed aansloten). Dit is niet de fout van MySQL omdat de programmeur dient aan te geven in welke encodering deze wenst te werken!

Dit artikeltje beschrijft dit principe en een soortgelijk geval van wat er misgegaan kan zijn, en hoe je dit weer op kunt lossen. Het is jouw verantwoordelijkheid om uit te zoeken wat er in jouw geval aan de hand is. Maar dit zou je wat ideeën kunnen geven waar te beginnen.

Toevoeging op 09/11/2015 09:25:21:

SNELLE TEST
Vul via je applicatie de volgende tekst (zonder spaties of regelovergangen, enkel deze zin op een enkele regel) in in een tabel/kolom:

Schönen Tag, Welt!

Controleer vervolgens hiervan (via een scriptje, via PHPMyAdmin, via een rechtstreekse verbinding (console), doet er niet toe) de HEX() waarde van deze tekst.

Als deze ongelijk is aan:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
536368C3B66E656E205461672C2057656C7421

Dan heb je een probleem.

Als deze bijvoorbeeld gelijk is aan:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
536368C383C2B66E656E205461672C2057656C7421

Dan staat je data niet als UTF-8 opgeslagen in je database en zul je je data moeten repareren middels een conversie en tevens je connectie-parameters moeten aanpassen.
Gewijzigd op 09/11/2015 09:35:08 door Thomas van den Heuvel
 
J opla

j opla

09/11/2015 10:28:16
Quote Anchor link
@Thomas

Dank je voor je zeer uitgebreide reactie. Het is een moeilijk te doorgronden materie voor mij. Bovendien is het al een paar jaar geleden dat ik de codes heb geschreven, dus helemaal fris is het niet meer voor me.

Vermoedelijk heeft eerder de tabel in "latin1" gestaan. Ooit heb ik wel de tabel via phpMyAdmin omgezet naar UTF-8 en ik denk dat ik er dan ook maar van uit ben gegaan dat daarmee de inhoud ook in UTF-8 zou zijn gewijzigd. Wat ik van jou begrijp is dat waarschijnlijk niet het geval. De data is grotendeels via phpMyAdmin toegevoegd, alleen de laatste tijd via een script. Meestal pas ik daarna handmatig in phpMyAdmin foute tekens aan. Overigens is de tekst in phpMyAdmin wel goed leesbaar ...

Om even van scratch te beginnen:

1. De HTML code
De website staat volgens mij netjes in UTF-8 met de volgende header:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<!DOCTYPE html>
<html lang="nl">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="UTF-8" />
</html>

Ik weet niet of de eerste <meta>-regel eigenlijk nog nodig is, volgens mij niet, maar misschien kan iemand daar uitsluitsel over geven.

2. De PHP-code
Als het goed is draait php in UTF-8. Dit heb ik geregeld via een toevoeging in .htaccess
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
php_value default_charset "utf-8"
AddDefaultCharset utf-8

Ook hier lijkt het weer dubbelop, misschien kun je daar uitsluitsel over geven?

3. Databaseverbinding
Ik heb nergens volgens mij staan dat de databaseverbinding in UTF-8 moet zijn. De volgende regel gebruik ik voor een databaseverbinding:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?
$dblink
= mysqli_connect('localhost', 'user', 'wachtwoord', 'database');
    if(!$dblink)
    {

        trigger_error('Fout bij verbinden met database: '.mysqli_connect_error());
    }

?>

Kennelijk moet ik hier iets aan toevoegen. Maar wat? Ik kan wel wat vinden in de manuals maar dat is om de set uit te lezen volgens mij.

Als ik deze 3 items duidelijk heb, dan heb ik nog wel vragen over het opschonen van de database, maar daar kom ik dan wel bij je op terug (als dat mag).
 
Frank Nietbelangrijk

Frank Nietbelangrijk

09/11/2015 10:53:05
Quote Anchor link
Voeg na een succesvolle mysqli_connect het volgende toe:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
mysqli_set_charset($dblink, 'utf8');
?>


Toevoeging op 09/11/2015 10:54:49:

In PHP kun je eventueel nog een header meegeven aan je response. Deze moet vrijwel bovenaan in het script komen nog voor er enige output verstuurd wordt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
header('Content-Type: text/html; charset=utf-8');
?>
 
Thomas van den Heuvel

Thomas van den Heuvel

09/11/2015 10:56:38
Quote Anchor link
EDIT: NEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE Frank, dat kun je niet zomaar doen!!! LEES HIERONDER

Quote:
Vermoedelijk heeft eerder de tabel in "latin1" gestaan. Ooit heb ik wel de tabel via phpMyAdmin omgezet naar UTF-8 en ik denk dat ik er dan ook maar van uit ben gegaan dat daarmee de inhoud ook in UTF-8 zou zijn gewijzigd.

Als je oorspronkelijke een latin1 tabel had met latin1 encoded data dan zou deze zonder problemen omgezet moeten kunnen worden met een ALTER TABLE statement. Ook de data in de tabel wordt dan geconverteerd naar de nieuwe character encodering.

@1: een van de twee meta tags is afdoende, ook zou je vanuit PHP een Content-Type header mee kunnen sturen met een vermelding van de character encoding:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
header('Content-Type: text/html; charset=UTF-8');
?>

Als je enkel een meta tag gebruikt is het belangrijk dat dit de eerste tag is binnen je <head>-tag, dus nog voor je <title>. Het is aan te raden (maar niet verplicht) om ook een PHP-header te gebruiken zodat je browser meteen in de goede "modus" zit als die het document binnenhaalt/leest etc. Als je de PHP header weglaat zou de browser tijdens het lezen van het document kunnen besluiten om het document opnieuw te gaan lezen naar aanleiding van de metatag omdat dit afwijkt van de default "leesmode", maar dit maakt verder voor snelheid eigenlijk niets meer uit tegenwoordig.

@2: dit kan nooit kwaad maar heeft in beginsel volgens mij niet zoveel invloed op de correcte werking van weergave van data vanuit je database; dit zou wel van invloed kunnen zijn op het gedrag van enkele functies, maar als je daarin expliciet een character encoding kan aangeven (denk htmlentities(), htmlspecialchars() etc.) lijkt mij dit altijd de voorkeur hebben boven het simpelweg uitgaan van een default.

@3: hier zit een potentieel probleem; ik zal dit zo simpel mogelijk proberen uit te leggen. Hierbij is het heel belangrijk dat er eigenlijk nog niets veranderd wordt zolang je geen duidelijk beeld hebt van wat er aan de hand is. Het zit als volgt: in principe kun je met de functie set_charset() een character encoding instellen. Je moet dit denk ik als volgt interpreteren: hiermee zeg je in feite tegen MySQL: "Ik wil mijn data in character encoding X ontvangen, en als ik iets wegschrijf zorg ik dat ik dit in character encoding X aanlever". Default is de character encoding waarmee je met je database communiceert latin1.

Nu is er dus het volgende aan de hand: je hebt een UTF-8 website en een utf8 database (utf8 is de UTF-8 character encoding in MySQL) maar een latin1 connectie. Vervolgens ga je sleuren en pleuren met data, dit is wat er gebeurt:

* bij het ophalen van data
Jij vraagt aan MySQL "geef mij record X". MySQL ziet "Hey, deze tabel/kolom is utf8, maar mijn gebruiker wil latin1 data ontvangen". MySQL vertaalt vervolgens de utf8-data naar latin1 en stuurt deze naar de PHP-kant.

* bij het wegschrijven van data
Je levert je data UTF-8 aan (immers, je site was UTF-8) maar je connectie is latin1 en MySQL is ook in de veronderstelling dat wat jij aanlevert latin1 is, terwijl dit dus in werkelijkheid UTF-8 data is. MySQL ziet dus vervolgens: "Hey, ik ontvang latin1 data (eigenlijk UTF-8 dus) maar de tabel waarin ik alles weg moet schrijven is utf8". MySQL voert vervolgens dus een vertaling uit naar utf8 die eigenlijk niet nodig was.

Je data is dus een beetje door de mangel gehaald bij wegschrijven, maar omdat je ook weer een vertaalslag terug maakt als je je data weer ophaalt gaat dit soms/af-en-toe/when-the-stars-are-right goed.

Echter, je kunt nu niet zonder meer je connectie corrigeren omdat dit twee ongewenste effecten heeft:
- de data die in je database zit wordt nu gewoon aangeleverd as-is (je connectie is utf8, je data tabel- en kolomdefinities zijn utf8, MySQL vindt dan terecht dat er geen vertaling nodig is). Echter, de DATA is niet utf8 dus grote kans dat je data niet goed wordt weergegeven

- de data die je vanaf dat punt naar je database schrijft is wel in correct UTF-8 format; het LAATSTE wat je wilt is dat je op een zeker moment een mix hebt van corrupte en kloppende data omdat je dan per tabel het omslagpunt moet weten vanaf waar/tot wanneer je je corrupte data moet gaan repareren, het is heel belangrijk dat je een "clean break" hebt tussen oude en nieuwe situatie waarbij je je corrupte data repareert en (meteen daarna, zonder wijzigingen/toevoegingen tussendoor) je je connectie-credentials fixt anders heb je dus te maken met het zojuist beschreven scenario van corrupt/kloppend door elkaar
Gewijzigd op 09/11/2015 11:26:58 door Thomas van den Heuvel
 
Frank Nietbelangrijk

Frank Nietbelangrijk

09/11/2015 11:07:54
Quote Anchor link
Lijkt me beter om de data in de database aan te passen naar UTF8 Thomas. En ja natuurlijk ging ik er gemakshalve van uit dat Jo 'gewoon' wilde overstappen op UTF8 en dus ook de data zo gaat opslaan/converteren.
 
Thomas van den Heuvel

Thomas van den Heuvel

09/11/2015 11:16:19
Quote Anchor link
Indien de data in de tabellen te allen tijde de voorgeschreven character encoding hadden dan kun je de character encoding van set_charset() af laten hangen van hoe je je data wilt weergeven (en je moet er dan voor zorgen dat je ook data aanlevert in deze CE als je iets weg wilt schrijven).

Gegeven de oorspronkelijke situatieschets lijkt het er niet op dat we hier van uit kunnen gaan. Daarom zal stapsgewijs een analyse gemaakt moeten worden en vervolgens een soort van plan van aanpak opgesteld moeten worden.

Simpelweg set_charset() "omgooien" naar utf8 en dan kijken waar het schip strandt, ik denk dat je daarmee alleen maar meer ellende over je afroept.
 

09/11/2015 13:17:32
Quote Anchor link
Deze is eenvoudig volgens mij:
Quote:
Als ik "htmlentities" weg laat dan krijg ik een "zwart wiebertje met een ?" (?) op de plaats van de ringels (ß).

Dit betekent dat het weglaten van htmlentities() er voor zorgt dat het UTF-8 karakter niet wordt weergegeven, hetzij omdat de data niet klopt of omdat de aangegeven encoding van je site niet klopt.
Check:
Doe vanuit je .php:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
header('Content-type: text/plain; charset=utf-8');
print 'ß';
?>

=> http://www.w3.org/International/O-HTTP-charset
En sla je PHP-bestand in ieder geval voor deze test op als UTF-8.
Dat moet goedgaan, en je zult merken dat je die hele htmlentities functie niet meer nodig hebt.(!)

Quote:
De database staat in UTF-8, de site ook.

En de connectie? Als je dat niet specificeert staat de connectie in Latin1 by default... (suf he..)
Kan je aanpassen met:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
SET NAMES 'UTF8';

En/of
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$db
= mysqli(...);
print $db->get_charset();
?>

=> http://php.net/manual/en/mysqli.get-charset.php
Daar MOET UTF-8 uit komen, anders kan je hem instellen met mysqli::set_charset();

Quote:
Als ik de flags "ENT_HTML5, "ISO-8859-1" toe voeg dan verschijnt de tekst wel goed, maar dat lijkt me vreemd omdat voilgens mij alles in UTF-8 zou moeten staan ...

Dit bewijst dat jouw data (eenmaal in PHP aangekomen uit MySQL via de connectie) NIET in UTF-8 staat, maar in Latin1. Dat kan verklaard door de databaseconnectie.
En dit verklaart ook waarom het anders is in PHP 5.6 ten opzichte van 5.4. Van http://php.net/manual/en/function.htmlentities.php :
Quote:
If omitted, the default value of the encoding varies depending on the PHP version in use. In PHP 5.6 and later, the default_charset configuration option is used as the default value. PHP 5.4 and 5.5 will use UTF-8 as the default. Earlier versions of PHP use ISO-8859-1.

Ofwel, je moet tegenwoordig jouw data in UTF-8 aanleveren, niet meer als Latin1. Oplossingen:
1.) Stel de optie in
2.) Laat PHP je data weer UTF-8 maken via utf8_encode()
3.) stel de connectie in als UTF-8

Optie 3 is natuurlijk het beste, want dan zadel je PHP niet op met een taak die voorkomen kan worden. En als de gegevens niet getranscodeerd worden, kan er ook geen verlies van data optreden.

Voor ik het vergeet, Frank en Thomas hebben beide gelijk wat betreft de database. Om zeker te weten dat je data UTF-8 is moeten de tekstkolommen de utf8 encoding hebben, dat kan je makkelijk checken met een tooltje als phpMyAdmin.
Let wel dat de utf8 encoding van MySQL lang niet alle unicode karakters ondersteunt, net als PHP. Alleen de eerste plane wordt ondersteunt. Mocht je dat wel willen dan moet je de utf8mb4 encoding gebruiken. En een lettertype dat die unicode karaketers kan printen. Als je alleen europese talen als Duits gebruik, en niet het Klingons kan je je rustig beperken tot de eerste plane. =]
https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
Gewijzigd op 09/11/2015 13:33:46 door
 
Thomas van den Heuvel

Thomas van den Heuvel

09/11/2015 14:17:25
Quote Anchor link
An tje op 09/11/2015 13:17:32:
Kan je aanpassen met:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
SET NAMES 'UTF8';

Dit raadt php.net AF, zie de notities op deze pagina. Tenzij je je CE instelt met set_charset() zal je output escaping in MySQL niet goed werken...

An tje op 09/11/2015 13:17:32:
2.) Laat PHP je data weer UTF-8 maken via utf8_encode()

Dat is geen oplossing maar symptoombestrijding, het lijkt mij beter om het onderliggende probleem weg te nemen.

An tje op 09/11/2015 13:17:32:
Om zeker te weten dat je data UTF-8 is moeten de tekstkolommen de utf8 encoding hebben, dat kan je makkelijk checken met een tooltje als phpMyAdmin.

Dit is een noodzakelijke voorwaarde: de tabellen/kolommen (de structuur dus) moeten een utf8-encoding voorschrijven, maar dit zegt niets over de DATA die in deze kolommen staat opgeslagen. Het probleem is juist dat deze data (naar alle waarschijnlijkheid) niet correct is geëncodeerd.

Tenzij je deze uitgangssituatie kloppend maakt (utf8 DATA in een utf8 tabel) kun je geen enkele garantie afgeven over de kloppendheid van wat voor vervolgactie dan ook.
Gewijzigd op 09/11/2015 14:18:38 door Thomas van den Heuvel
 
J opla

j opla

09/11/2015 14:30:15
Quote Anchor link
@allen
Dank voor al jullie input. Ik ga het vanavond op mijn gemak allemaal bekijken en eventueel aanvullende vragen stellen. Ik zag wat tegenstrijdigheden in de adviezen. Ik hoop niet te veel ;-)
 

09/11/2015 17:51:03
Quote Anchor link
Oké! :) Samenvattend: alles moet simpelweg in UTF-8.

Kortste volledige checklist:

1.) de encoding van teksten in de database, minimaal utf8

2.) de encoding van de connectie met mysqli, bij voorkeur met set_charset()

3.) de encoding van data in PHP wil je het liefst niet aantasten, gebruik ipv. alle oude string functies de multi-byte tegenhanger, dus geen strlen(), substr() etc, maar mb_strlen(), mb_substr() etc. anders kan de data corrupt raken. Doe een handmatig gecontroleerde find-replace door je volledige sourcecode.

4.) de encoding van data afkostig uit je PHP-bronbestand moet utf8 gemaakt worden, het is het meest eenvoudig om je PHP-bestanden in UTF8 op te slaan. Latin1 kan ook, maar dan moet je alle strings eerst UTF8 maken, met utf8_encode bijvoorbeeld.

5.) de meeste PHP-extenties verwachten data in UTF8, zoals XMLWriter en DOMDocument. Ik sluit niet uit dat er extenties bestaan die een andere encoding vragen. (htmlentities is ook nog maar net veranderd), waar nodig moet je handmatig transcodingfuncties gebruiken.

6.) op alle plekken waar geen transcoding meer nodig is, kan je alle htmlentities-achtige functies weglaten. Zo hoef je je data niet eerst door utf8_encode() te halen voordat je json_encode() gebruikt.

7.) stuur alle data in UTF8 naar de browser, en vermeld eenduidig de encoding aan de browser via HTTP header. NIET in de HTML5-code via de CHARSET metatag. Dat was misschien ooit handig voor polyglot HTML, maar met HTML5 ...

8.) Om het cirkeltje rond te maken moet je zeker zijn dat de input van de browser die in PHP aankomt valide UTF8 is. Er zijn byte sequences denkbaar die dat niet zijn, wat gebruikt kan worden om te hacken.
Je kunt de W3C regex daarvoor gebruiken:
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
<?php
function is_utf8($sData){
  // Ensure contents is valid UTF-8 using W3C recommended regex
  return preg_match('%^(?:
      [\x09\x0A\x0D\x20-\x7E]            # ASCII
    | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
    | \xE0[\xA0-\xBF][\x80-\xBF]         # excluding overlongs
    | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
    | \xED[\x80-\x9F][\x80-\xBF]         # excluding surrogates
    | \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
    | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
    | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
  )*$%xs'
, $sData);
}

?>


Nog een paar handig tips:
- stel de encoding van mb_* functies expliciet in op UTF8 aan het begin (bootstrap) van je PHP:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
mb_internal_encoding('UTF-8');

- mochten de mb_* -functies van PHP niet voldoende zijn, dan zijn er genoeg libraries op internet te vinden met aanvullende functionaliteit.
- De encoding van PHP-bestanden moet ASCII-compatible zijn, en UTF8 is ASCII-compatible.
Je kunt met dank aan UTF8 je PHP-bestanden dus zorgeloos als UTF8 opslaan.
- PHP is niet ideaal voor databewerkingen, waar dat kan wil je alles zoveel mogelijk in-database oplossen
Gewijzigd op 09/11/2015 17:54:10 door
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

09/11/2015 18:41:12
Quote Anchor link
‘probeer dit eens op te slaan in een kolom met charset utf8’

Dit gaat onherroepelijk een SQL fout opleveren.

De moraal: Mysql's utf8 is niet gelijkwaardig aan de 'officiële' utf8, in MySQL gebruik je hiervoor de charset mb4utf8
 

09/11/2015 20:05:46
Quote Anchor link
Afgezien van het feit dat de string van Ger Latin1 is met dank aan deze site ;-) begrijp ik niet waarom het tot fouten zou leiden voor MySQL. Ja, utf8mb4 biedt volledige Unicode dekking voor MySQL, maar in mijn beleving is het waarschijnlijker dat PHP 5 zelf problemen geeft met UTF8. Ik ging daarnet even browser en kwam dit stukje tegen: http://stackoverflow.com/questions/571694/what-factors-make-php-unicode-incompatible
En ik moet zeggen dat als ik dat lees, ik het liefst mijn appje in vollediger taal zou willen herschrijven, ware het niet dat het wel veel werk is in 1x. (zit nu in migratie van MySQL naar PostgreSQL).
Verder is alom bekend dat PHP 6 en volledige Unicode support ook nog niet gelukt is, hopelijk brengt PHP 7 verbetering.
 
J opla

j opla

09/11/2015 20:59:19
Quote Anchor link
Wat een hoop reacties en tekst. Een en ander roept wat vragen op.
Quote:
Thomas:
@1 ... Als je de PHP header weglaat zou de browser tijdens het lezen van het document kunnen besluiten om het document opnieuw te gaan lezen naar aanleiding van de metatag omdat dit afwijkt van de default "leesmode", maar dit maakt verder voor snelheid eigenlijk niets meer uit tegenwoordig.

Grappig. Maar dat zou betekenen als je een pagina zonder php op maakt dat de browser ook opnieuw zou kunnen starten ...
header() moet dan voor de eerste html output staan neem ik aan.

@2 ... Maakt het nog wat uit welke van de 2 regels (php_value default_charset "utf-8" en
AddDefaultCharset utf-8 ) in de .htaccess zouden moeten staan? Of zijn ze aanvullend aan elkaar?

@3 ... het instellen van de charset voor de databaseverbinding. Heeft die betrekking op ingaand verkeer (iets naar de database toe schrijven), uitgaand verkeer, of op beide?

Quote:
Thomas:
Als je oorspronkelijke een latin1 tabel had met latin1 encoded data dan zou deze zonder problemen omgezet moeten kunnen worden met een ALTER TABLE statement. Ook de data in de tabel wordt dan geconverteerd naar de nieuwe character encodering.

Als ik via phpMyAdmin de charset heb gewijzigd, dan heeft op de achtergrond ALTER TABLE gedraaid volgens mij. Net even geprobeerd en ik zie dat de volgende sql wordt uitgevoerd:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
ALTER TABLE `m_boeken` CHANGE `auteur` `auteur` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ;

In phpMyAdmin ziet de tekst er correct uit. Mag ik daarmee concluderen dat de tekst als utf-8 in de tabel zit? Zo ja, dan zou alleen de ontbrekende codering van de databaseverbinding het probleem zijn ...

Verder zie ik iets over mb_strlen ipv strlen. In de documentatie zie ik niets dat er op wijst dat strlen niet meer correct is in php5. Is dit misschien iets voor toekomstige ontwikkelingen?

Dat was het even voor dit moment,

Nogmaals bedankt voor alle input en hopelijk krijg ik nog even een eenduidige reactie op bovenstaande.

Jop

Toevoeging op 09/11/2015 21:03:18:

Quote:
mysqli_set_charset($dblink, 'utf8');

Klopt het dat het utf8 is en geen utf-8?
Gewijzigd op 09/11/2015 21:03:50 door j opla
 

09/11/2015 21:06:35
Quote Anchor link
Quote:
@3 ... het instellen van de charset voor de databaseverbinding. Heeft die betrekking op ingaand verkeer (iets naar de database toe schrijven), uitgaand verkeer, of op beide?

Beide

Quote:
dan zou alleen de ontbrekende codering van de databaseverbinding het probleem zijn ...

Dat probeer ik je duidelijk te maken ;)

Quote:
In de documentatie zie ik niets dat er op wijst dat strlen niet meer correct is in php5.

De functie strlen werkt op byte niveau, het telt het aantal bytes. Bij Latin1 (single byte character set) staat dat gelijk aan het aantal karakters.
UTF8 slaat karakters op in 1 t/m 4 of 6 bytes. Dus krijg je met strlen() op een UTF8 tekst als 'überhaupt' een andere lengte dan met mb_strlen(), die laatste telt wel het aantal karakters van een multi-byte string.
Hou je daar geen rekening mee dan kan het de werking van je programma verpesten.
Het hangt van de programma af, of het PHP-deel informatie bewerkt of alleen doorgeeft tussen browser <=> database.
Gewijzigd op 09/11/2015 21:09:54 door
 
Thomas van den Heuvel

Thomas van den Heuvel

09/11/2015 23:12:42
Quote Anchor link
Ik haak af in dit topic. Al de informatie die hier gespuid wordt kan beter gebundeld worden in een tutorial of artikel, maar het heeft volgens mij weinig meer van doen met de oorspronkelijke vraag van de topicstarter.

Mocht je nog informatie willen PM me maar.
 
Eddy E

Eddy E

11/11/2015 19:38:07
Quote Anchor link
Toch is dit wel een van de betere, meer inhoudelijke topics met goede argumenten. Dus het lezen waard. Kost wel wat tijd, maar dan heb je ook wat.
 
J opla

j opla

12/11/2015 10:23:01
Quote Anchor link
Beste allen,

Allemaal bedankt voor jullie input. Extra informatie is helemaal niet verkeerd. Maar het kan ook verwarrend en diffuus worden. Als gebruiker van dit forum voel ik me soms van het kluit in het riet gestuurd worden omdat ik te veel informatie krijg of niet relevante informatie. Wellicht goed, bezien vanuit mijn positie als vragensteller, om een aantal zaken in de gaten te houden bij het beantwoorden, denk ik:
- wat is precies de vraag?
- als je twijfelt over de vraag, stel dan gerichte wedervragen om de vraagstelling te verduidelijken.
- beter geen antwoord dan het antwoord op een andere vraag
- probeer met je antwoord rekening te houden met het niveau van de vraagsteller
- probeer een antwoord te formuleren dat niet meer vragen op roept dan nodig
- verwijzingen naar andere documentatie (in dit geval niet echt van toepassing) is als achtergrond informatie vaak leuk, maar als antwoord niet echt duidelijk. Vaak heb ik al verschillende zaken bekeken voor ik hier een vraag stel. Mocht je verwijzen naar andere documentatie, geef dan duidelijk aan waar het antwoord volgens jou in die documentatie te vinden is.
- probeer in je antwoord niet te veel zijpaden op te gaan, en als je een zijpad op gaat geef dan duidelijk aan wat en waarom dat zijpad wordt bewandeld. Het verhaal van die mb-str* functies is op zich interssant, maar blijkt vooral van toepassing als je in strings met special characters wilt gaan plakken en knippen. Dat was hier helemaal niet het geval. Leuk om te weten, maar werkte voor mij verwarrend.
- probeer als het even kan een concreet voorbeeld te geven.
- geef aan waarom je iets op een bepaalde manier zou moeten doen, daar leer ik van, dan kan ik het hopelijk de volgende keer zelf ;-)
- probeer een antwoord van een ander niet over te doen, tenzij er pertinente onzin in staat volgens jou.

Zo geef ik op een gegeven moment aan dat ik het allemaal ga bestuderen en als het nodig is dat ik dan extra vragen zal stellen om eea meer duidelijk te krijgen. Voor ik eventueel aanvullende vragen had gesteld, wordt er al een berg aan aanvullende informatie uitgestort. Dat werkte voor mij alleen maar verwarrend.

Hopelijk maakt deze reactie de kwaliteit van dit forum nog beter. Nogmaals, iedereen bedankt voor hun input en bijdragen!

Jop

PS het probleem was opgelost met het instellen van de charset voor de db-verbinding.
Gewijzigd op 12/11/2015 10:27:41 door j opla
 

12/11/2015 11:52:35
Quote Anchor link
Beste jo, bedankt voor je terugkoppeling. De info die over je wordt uitgestort was wel wat veel inderdaad, een leermomentje voor ons.
 

23/11/2015 14:23:50
Quote Anchor link
Voor wie nooit meer dit soort problemen wil is er een tut op:
http://www.phphulp.nl/php/tutorial/php-algemeen/unicode-enzo/831
 
J opla

j opla

24/11/2015 21:48:40
Quote Anchor link
Goed idee An tje! Ik heb je een mail gestuurd met wat tips.
 



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.