PHP encoding tekst speciale characters
Ik importeer een Excel via PHPExcel in de MySQL database. Dat werkte op zich goed. Nu weet ik niet helemaal of het met een nieuwere excel te maken heeft maar opeens kreeg ik onlangs een error 'Detected an illegal character in input string 'filenaam' on line xx"
Toen een beetje googlen en heb ik er 'utf8_encode voor de waarde gezet. Ik kreeg niet de bovenstaande error meer maar ik zie nu bv.
Antoniële omgezet worden in "Antoniëlla'
Dit is de regel code.
Code (php)
1
2
3
2
3
<?php
$imp_data[$ic] = iconv("UTF-8", "ISO-8859-1", utf8_encode($cell->getFormattedValue()));
?>
$imp_data[$ic] = iconv("UTF-8", "ISO-8859-1", utf8_encode($cell->getFormattedValue()));
?>
Kan iemand mij helpen wat het nu moet zijn? Ik ben in het verleden hier ook al eens mee aan het klooien geweest.
Nico
Waar je alleen voor moet zorgen is dat de collatie van je database (danwel tabel, danwel kolom) goed staat. Dat je connectie met de database correct is ingesteld op utf8 en dat je de juiste headers aan je html pagina geeft (ook utf8) zodat elk onderdeel in de keten weet hoe de bytes gelezen en getoond moeten worden.
Wat je moet doen ( wel ... wat ik aanraad ), is alles in UTF-8 zetten.
De database tabel moet in UTF-8 staan.
De HTML pagina moet een UTF-8 meta tag hebben.
Stuur (net voor de eerste echo) een UTF-8 header.
Ik denk dat daarmee de problemen meestal opgelost zijn.
---
Iets anders ... al eens geprobeerd om dat niet rechtstreeks via het gesloten Excell-formaat te doen, maar via csv?
Sla het document op als .csv, dan het je een document dat niet verschilt afhankelijk van de Excell versie.
Ik heb mijn collatie op latin_swedish_c1 staan. Ik weet niet waarom ik heb dat ooit overgenomen van iemand. Wat voor ons eigenlijk de beste collatie is weet ik niet.
Ik heb wel even de collatie op utf8_unicode_c1 gezet en opnieuw de import gedaan maar ik zie in de logging dat het al fout is. Garbish in = Garbish out.
Misschien een domme vraag maar hoe stel je de connectie op utf8 in? Ik gebruik zowel bij inlezen als teruglezen dezelfde connectie. Ik heb class gemaakt voor de connectie met Server, DB, User, WW. Meer parameters ken ik niet.
***** EDIT *****
Nu heb ik er weer dit van gemaakt:
En nu zijn de namen weer correct.
Ik heb dit enkele weken geleden aangepast omdat er iets anders op stuk liep.
Gewijzigd op 24/10/2013 12:47:49 door nkamp Kamp van de
ps. hiermee wil ik niet zeggen dat je moet afstappen van latin_swedish_c1 en over moet naar utf8. Kies de collatie die voor jou het beste is, alleen zorg ervoor dat je daar dan ook consequent mee werkt. Mixen van collaties is nooit een goed idee.
Maar ik heb nu de encode weer terug gezet, dus dit is nu weer:
Code (php)
1
2
3
2
3
<?php
$imp_data[$ic] = iconv("UTF-8", "ISO-8859-1", utf8_encode($cell->getFormattedValue()));
?>
$imp_data[$ic] = iconv("UTF-8", "ISO-8859-1", utf8_encode($cell->getFormattedValue()));
?>
Maar ik heb html pagina en daar heb ik een import button die een pop-up scherm opent de Excel uitleest en importeert naar de MySQL database. Dit was enkel PHP maar heb ik nu het volgende aan toegevoegd nl. html tags:
...code
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
</head>
<body>
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
... de excel uitlezen met for loop
$imp_data[$ic] = iconv("UTF-8", "ISO-8859-1", utf8_encode($cell->getFormattedValue()));
//En dan deze regel is mijn logging:
echo '<td style="border-right: 0px;">', $imp_data[$ic],'</td><td style="border-left: 0px;">(', $cell->getCoordinate() ,')</td>' , PHP_EOL;
?>
... de excel uitlezen met for loop
$imp_data[$ic] = iconv("UTF-8", "ISO-8859-1", utf8_encode($cell->getFormattedValue()));
//En dan deze regel is mijn logging:
echo '<td style="border-right: 0px;">', $imp_data[$ic],'</td><td style="border-left: 0px;">(', $cell->getCoordinate() ,')</td>' , PHP_EOL;
?>
... code
</body>
</html>
hier wordt de array waarde $imp_data[$ic] weggeschreven naar het scherm en hier staat nu 'Antoniëlla (C186)'. En zo staat het ook in de database.
Dus het inlezen gaat al fout. Ik heb hier niet echt verstand van maar wat kan ik nu nog meer doen dat in ieder geval de import goed gaat?
Als ik zonder utf8_encode gaan de namen goed maar dan heb ik probleem met het inlezen van datum-tijd ':'.
Ik begrijp dat het aan de collatie ligt, en dat kan op meerdere fronten zijn, maar als ik eerst het inlezen maar werkend heb.
Toevoeging op 24/10/2013 15:11:39:
Ok, ik heb er nu dit van gemaakt:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
En nu wordt het correct in de logging weggeschreven. Het staat nu wel fout in de database.
Dus moet ik daar de collatie aanpassen? Ik denk dat ik maar weer utf8_encode_c1 doe, of in ieder geval probeer
Ten tweede, hoe meer stappen je hebt tussen het echte document en de import in de database, hoe meer kans je hebt op een foute vertaalslag ertussen. Bij elke stap zullen de bytes namelijk vetaald worden naar iets dat dat tool, of de taal kent en sommige karakters kunnen daarmee overhoop gegooid worden. De allerbeste methode is altijd een direct import in je database, zonder enig php geneuzel ertussen. Dus wat Kris ook al zei, exporteer bij voorkeur naar een CSV file en lees die direct in met een mysql commando of import tool. Als in zowel export als import de juiste karakterset/collatie gebruikt heb je de meeste kans op direct succes.
Op je laatste vraag heb ik al antwoord gegeven in mijn vorige post.
Ik ben al een stuk verder. Overigens csv doe ik niet want het gaat om een ledenlijst die ik niet eerst met de hand wil converteren naar csv en dan importeren.
Ik heb ook het boek van Ward van de Put nog eens even doorgekeken.
Ik heb de collatie gewoon latin_swedish_c1 gelaten.
Ik heb dus nu de meta regel:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
erin opgenomen.
Alternatief:
Ik heb de PDO driver gebruikt daar heb ik nu het volgende staan:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$db_Con = new PDO('mysql:host='.$this->server.';dbname='.$this->dbname, $this->gebr, $this->ww);
$db_Con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db_Con-> exec('SET CHARACTER SET utf8');
?>
$db_Con = new PDO('mysql:host='.$this->server.';dbname='.$this->dbname, $this->gebr, $this->ww);
$db_Con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db_Con-> exec('SET CHARACTER SET utf8');
?>
En nu wordt alles netjes de database in geïmporteerd en weer uitgelezen/gepresenteerd!
Ik heb het ook voor MySQLi werkend.
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$Mysqli = new mysqli($this->server, $this->gebr, $this->ww, $this->dbname);
$Mysqli->set_charset("utf8");
return $Mysqli;
?>
$Mysqli = new mysqli($this->server, $this->gebr, $this->ww, $this->dbname);
$Mysqli->set_charset("utf8");
return $Mysqli;
?>
Toevoeging op 24/10/2013 16:57:16:
Ok nog een kleine aanpassing in de presentatie.
Ik had daar de functie 'htmlentities', hierdoor ging het juist weer fout. Dit heb ik ervoor weg gehaald en nu werkt het correct.
Ik heb het nu 'WERKEND' gemaakt. Maar het is mij nog niet geheel duidelijk bv. wanneer of waarom kies je UTF-8 collotie en wanneer/waarom latin-swedish?
En ik heb het nu in de connectie ingebouwd maar waar-waarom en wanneer je dit allemaal doet is mij niet duidelijk. Zoals ik al zei ik heb het werkend gemaakt nav. de opmerkingen van Erwin en Kris hierboven.
Bedankt, ik vind nu wel leuk dat het 'cirkeltje' rond, ik bedoel vanuit Excel inlezen t/m presentatie.
Gewijzigd op 24/10/2013 16:35:47 door nkamp Kamp van de