Last couple of hours i have tried hard but failed to come into a solution. why it's happening....
I have a table with collation=utf8_general_ci and it's column/field collation is also set to utf8_general_ci.
i can see thai data properly from phpmyadmin. but when i fetch this table data and show using php code it shows ???????
click to have a look the page.
in this page i have written one thai word directly which shows properly but same word/text when i fetch from database and display it shows ???
i am using
<meta http-equiv="Content-Type" content="text/html; charset=tis-620">
currently and when i have tried with
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
i found Direct and from Database both text/word display as ?????
It may be possible that your MySQL connection itself is not using utf8. From the MySQL manual:
SET NAMES indicates what character set the client will use to send SQL statements
to the server. Thus, SET NAMES 'cp1251' tells the server, “future incoming
messages from this client are in character set cp1251.” It also specifies the
character set that the server should use for sending results back to the client.
(For example, it indicates what character set to use for column values if you use
a SELECT statement.)
Depending on how you are connecting to the database (mysql_connect/mysqli_connect or PDO) the steps are a little bit different. If using mysql_connect(); or mysqli_connect; then you will need to run a mysql_query("SET NAMES utf8");. In thoery you can use the same steps if using PHP PDO but you can alternatively set the init command during PDO object construction. Here's an example from a database interaction class of mine.
$dsn = 'mysql:host='.$database_detail['dbhost'].';dbname='.$database_detail['dbname'];
$this->dbh = new PDO($dsn, $database_detail['dbuser'],
$database_detail['dbpass'], array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
));
I have this problem with Spanish sometimes, and even though I set the content type in html it still displays the wrong encoding type.
What works for me is if I "save the php document" with the correct formatting and then that fixes the issue.
You see when your document gets severed from Apache, or whatever your using, it sends the document type that it reads, but your PHP code is dynamically getting the content from the database.
So I would do the following:
Write the thai word in HTML and get it to display correctly. Try doing this by saving the document in different encoding options. This is normally the option in the save dialog, and once you have it displaying then try fetching it from the Database.
Of course, you could force Apache to serve documents in the encoding you want, but this assumes that you have access to those settings.
I hope that helps.
Related
I've met and interesting behavior with PDO which relates to UTF-8 encoding issues.
When inserting data I need to declare SET NAMES UTF-8 for data to be stored correctly. Ok so this is fine. BUT!
When selecting data (and fetching results) I specifically can't SET NAMES UTF-8, or otherwise the characters gets scrambled. Or if I use set names UTF-8 for selects I need to utf8decode the result set (as in translate to iso88591) if I want to see them correctly. This would suggest that my page would be interpreted as iso88591. However if I reduce my page to single page app (its an angularjs/PHP slim/pdo setup) the same functionality remains - UTF-8 names for pdo init for $http.post and explicitly no set names UTF-8 for select / $http.get. Also if I die and expose the data after fetching the results from UTF-8 collated table I need decode them to see correct data.
I made this hack in my db adapter construct to get around it but I rather would like to solve the whole issue since it has made me curious:
$init = array();
if ($write) {
$init = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8");
}
$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS, $init);
Some facts:
all associated files are UTF-8.
all (search, view, insert) pages are correctly as "text/HTML;charset=UTF-8" (and of course there is the fact that I reduced all functionalities to one page and still could replicate this scenario)
headers from debugger translated as UTF-8.
PHP detects strings (insert and search) as UTF-8 when echoed in controller from request parameters BEFORE sql insert/select.
PHP ini default charset is UTF-8.
MySQL database and table charset UTF-8 and collation UTF-8 general.
editor is atom.
environment ubuntu 14.
Has anyone else encountered anything similar behavior? Could this have to do something with the headers sent with angular (XHR) as they are default? Though after the request and params are interpreted correctly as UTF-8 by server side so it would seem far fetched. There is a chance that this might have a mystical link to environment since its not a fresh vm but a local dev machine that has its own tweaks on it.
I am using PHP 5.3.3 and MySQL 5.1.61. The column in question is using UTF-8 encoding and the PHP file is encoded in UTF-8 without BOM.
When doing a MySQLi query with a ² character in SQLyog on Windows, the query executes properly and the correct search result displays.
If I do this same exact query in PHP, it will execute but will show 0 affected_rows.
Here's what I tried:
Using both LIKE instead of =
Changing the encoding of the PHP file to ANSI, UTF-8 without BOM, and UTF-8
Doing 'SET NAMES utf-8' and 'latin1' before running the query
Did header('Content-Type: text/html; charset=UTF-8'); in PHP
Escaping using MySQLi::real_escape_string
Doing a filter_var($String, FILTER_SANITIZE_STRING)
Tried a MySQLi stmt bind
The only way I could get it to work properly is if I swapped the ² for a % and changed = to LIKE in PHP.
How can I get it query properly in PHP when using the ²?
You should be able to get the query to work by ensuring the following:
Prepping PHP for UTF-8
You first need to make sure the PHP pages that will be issuing these queries are served as UTF-8 encoded pages. This will ensure that any UTF-8 output coming from the database is displayed properly. In Firefox, you can check to see if this is the case by visiting the page you're interested in and using the View Page Info menu item. When you do so, you should see UTF-8 as the value for the page's Encoding. If the page isn't being served as UTF-8, you can do so one of two ways. Either you can set the encoding in a call to header(), like this:
header('Content-Type: text/html; charset=UTF-8');
Or, you can use a meta tag in your page's head block:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Prepping MySQL for UTF-8
Next up, you need to make sure the database is set up to use the UTF-8 encoding. This can be set at the server, database, table, or column levels. If you're on a shared host, you probably can only control the table and column levels of your hierarchy. If you have control of the server or database, you can check to see what character encoding they are using by issuing these two commands:
SHOW VARIABLES LIKE 'character_set_system';
SHOW VARIABLES LIKE 'character_set_database';
Changing the database level encoding can be done using a command like this:
(CREATE | ALTER) DATABASE ... DEFAULT CHARACTER SET utf8;
To see what character encoding a table uses, simply do:
SHOW CREATE TABLE myTable;
Similarly, here's how to change a table-level encoding:
(CREATE | ALTER) TABLE ... DEFAULT CHARACTER SET utf8;
I recommend setting the encoding as high as you possibly can in the hierarchy. This way, you don't have to remember to manually set it for new tables. Now, if your character encoding for a table is not already set to UTF-8, you can attempt to convert it using an alter statement like this:
ALTER TABLE ... CONVERT TO CHARACTER SET utf8;
Be very careful about using this statement! If you already have UTF-8 values in your tables, they may become corrupted when you attempt to convert. There are some ways to get around this, however.
Forcing MySQLi to Use UTF-8
Finally, before you connect to your database, make sure you issue the appropriate call to say that you are using the UTF-8 encoding. Here's how:
$db = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Change the character set to UTF-8 (have to do it early)
if(! $db->set_charset("utf8"))
{
printf("Error loading character set utf8: %sn", $db->error);
}
Once you do that, everything should hopefully work as expected. The only characters you need to worry about encoding are the big 5 for HTML: <, >, ', ", and &. You can handle that using the htmlspecialchars() function.
If you want to read more (and get links to additional resources), feel free to check out the articles I wrote about this process. There are two parts: Unicode and the Web: Part 1, and Unicode and the Web: Part 2. Good luck!
I am quite new to utf-8 encoding and have used htmlentities() ever since, but now want to change to have utf-8 in the database. I thought this might come in very handy, since as the website I am programming is German, I am using lots of umlauts.
However, it occurs to me I have a problem that I can't explain. In the html head, I say
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
For testing, if I type a plain "ö" and hardcode it in html, it is displayed fine.
Now here comes the queer thing: In my database, I have an entry "Köln" - in the database it looks exactly like this. However, when I get the string from the table with php and echo it out, it is echoed out as "K�ln".
On the other hand, if I type in umlauts and send that to the table with ajax, "Köln" - the string that I typed in - becomes "Köln" in the database.
I use the following code for that:
//Change city
$('#newcitybutton').click(function(){
//Get id and city
var id=encodeURIComponent($('#id').html()); //This does not seem to be the problem - if I leave that out, I still does the same thing
var city=$('#newcity').val();
//Call script to change city
$.ajax({
type: 'POST',
url: 'action/changecity.php',
data: 'id='+id+'&city='+city+'&kind='+kind,
success: function(feedback){
var json=$.parseJSON(feedback);
if(json.success=='false'){
$('#newcityfeedback').css('color','red').html(json.message).hide().fadeIn(200);
}else if(json.success=='true'){
$('#newcity').hide();
$('#newcitybutton').hide();
$('#'+kind+'city').html(decodeURIComponent(city));
$('#newcityfeedback').css('color','green').html(json.message).hide().fadeIn(200).delay(2000).fadeOut(200);
}
}
});
});
Changecity.php:
//Save in vars
$id=$_POST['id'];
$city=$_POST['city'];
$kind=$_POST['kind'];
//Update city
$query="UPDATE ".$kind."s SET city='$city' WHERE id=$id";
mysql_query($query);
I figured that when I use $city=utf8_decode($city); before putting in in the database, it is saved there correctly. But then I need to use utf8_encode to display it correctly on the page.
What am I doing wrong here? I just can't figure out whether the mistake comes from my code, or the database.
Try using the PHP function mysql_set_charset() with "UTF8" as parameter.
http://php.net/manual/en/function.mysql-set-charset.php
You also need to set the encoding used by MySQL for the current connection.
Using PDO, pass the following options to the PDO class constructor:
$pdoOptions = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
);
Using the the deprecated MySQL extension, execute the following query right after you created the connection:
mysql_query("SET NAMES utf8");
Check this stackoverflow question for more information: SET NAMES utf8 in MySQL?
You can set name encoding after db connection - follow this tutorial: http://www.oreillynet.com/onlamp/blog/2006/01/turning_mysql_data_in_latin1_t.html/
I'm trying to save French accents in my database, but they aren't saved like they should in the DB.For example, a "é" is saved as "é".I've tried to set my files to "Unicode (utf-8)", the fields in the DB are "utf8_general_ci" as well as the DB itself.When I look at my data posted through AJAX with Firebug, I see the accent passed as "é", so it's correct.Thanks and let me know you need more info!
Personally I solved the same issue by adding after the MySQL connection code:
mysql_set_charset("utf8");
or for mysqli:
mysqli_set_charset($conn, "utf8");
or the mysqli OOP equivalent:
$conn->set_charset("utf8");
And sometimes you'll have to define the main php charset by adding this code:
mb_internal_encoding('UTF-8');
On the client HTML side you have to add the following header data :
<meta http-equiv="Content-type" content="text/html;charset=utf-8" />
In order to use JSON AJAX results (e.g. by using jQuery), you should define the header by adding :
header("Content-type: application/json;charset=utf8");
json_encode(
some_data
);
This should do the trick
The best bet is that your database connection is not UTF-8 encoded - it is usually ISO-8859-1 by default.
Try sending a query
SET NAMES utf8;
after making the connection.
mysqli_set_charset($conn, "utf8");
if you use PDO, you must instanciate like that :
new \PDO("mysql:host=$host;dbname=$schema", $username, $password, array(\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8') );
Use UTF8:
Set a meta in your
<meta http-equiv="Content-type" content="text/html;charset=utf-8" />
When you connect to your mySQL DB, force encoding so you DONT have to play with your mysql settings
$conn = mysql_connect('server', 'user', 'password') or die('Could not connect to mysql server.');
mysql_select_db('mydb') or die('Could not select database.');
mysql_set_charset('utf8',$conn); //THIS IS THE IMPORTANT PART
If you use AJAX, set you encoding like this:
header('Content-type: text/html; charset=utf-8');
Have you reviewed http://dev.mysql.com/doc/refman/5.0/en/charset-unicode.html:
Client applications that need to
communicate with the server using
Unicode should set the client
character set accordingly; for
example, by issuing a SET NAMES 'utf8'
statement. ucs2 cannot be used as a
client character set, which means that
it does not work for SET NAMES or SET
CHARACTER SET. (See Section 9.1.4,
“Connection Character Sets and
Collations”.)
Further to that:
if you get data via php from your
mysql-db (everything utf-8) but still
get '?' for some special characters in
your browser (), try this:
after mysql_connect() , and
mysql_select_db() add this lines:
mysql_query("SET NAMES utf8");
worked for me. i tried first with the
utf8_encode, but this only worked for
äüöéè... and so on, but not for
kyrillic and other chars.
You need to a) make sure your tables are using a character encoding that can encode such characters (UTF-8 tends to be the go-to encoding these days) and b) make sure that your form submissions are being sent to the database in the same character encoding. You do this by saving your HTML/PHP/whatever files as UTF-8, and by including a meta tag in the head that tells the browser to use UTF-8 encoding.
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
Oh, and don't forget C, when connecting to the database, make sure you're actually using the correct character set by executing a SET NAMES charset=utf8 (might not be the correct syntax, I'll have to look up what it should be, but it will be along those lines)
PHP(.net) advises against setting charsets after connecting using a query like SET NAMES utf8 because your functionality for escaping data inside MySQL statements might not work as intended.
Do not use SET NAMES utf8 but use the appropriate ..._set_charset() function (or method) instead, in case you are using PHP.
Ok I have found a working solution for me :
Run this mysql command
show variables like 'char%';
Here you have many variables : "character_set_server", "character_set_system" etc.
In my case I have "é" for "é" in database and I want to show "é" on my website.
To work I have to change "character_set_server" value from "utf8mb4" to "latin1".
All my correct value are :
And other values are :
With theses values the wrong database accent are corrected and well displayed by the server.
But each case can be different.
what's up? :-)
I have one problem and i hope you can help me with it.
One friend of mine have a simple solid html website and i implemented little php; CRUD system for articles... problem i came across is placing and getting cyrillic characters from mysql database.
What i want to achive is next:
In the main navigation there are some separated sections, whose names, ids and item's order i want to place in mysql and than to pull names and to put each name as a link. Names are supposed to be cyrillic characters.
The problem comes when i, using php mysql_fetch_assoc function, try to display names which are inserted with cyrillic characters in database row, collation of row is utf8_general_ci, and i end with ????? insted of original characters. If i submit cyrillic characters via submit form to mysql it shows something like this У.
How can i solve this, thanks in advance!? :-)
Make sure you call this after connecting to database.
mysql_query("SET NAMES UTF8");
Also make sure that HTML file has charset meta tag set to UTF-8 or send header before output.
header("Content-Type: text/html; charset=utf-8");
I had the same problem until I encoded the 'Collation' column in my table to 'utf8_bin'.
if its really mysql fetch assoc messing up you should try:
mysql-set-charset
from the docs:
Note:
This is the preferred way to change
the charset. Using mysql_query() to
execute SET NAMES .. is not
recommended.
also make sure your files are saved as utf8 and check iconv_set_encoding / iconv_get_encoding
For anyone having more complex issues with legacy project upgrades from versions before PHP 5.6 and MYSQL 5.1 to PHP 7 & Latest MySQL/Percona/MariaDB etc...
If the project uses utf8_encode($value) you can either try removing the function from the value being prepared and use the accepted answer for setting UTF-8 encoding for all input.
--- OR ---
Try replacing utf8_encode($value) with mb_convert_encoding($value, 'utf-8')
PDO USERS
If you are using PDO here are two ways how to set utf8:
$options = [
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
];
new \PDO($dsn, $username, $passwd, $options);
--- OR ---
$dsn = 'mysql:host=localhost;charset=utf8;'
new \PDO($dsn, $username, $passwd);
I can confirm that mb_convert_encoding($value, 'utf-8') to SQL table using utf8_unicode_ci works for Cyrillic and Umlaut.