I have a web application I have been developing locally on my computer, I have recently launched it on my web server with the exact same settings for MySQL, but for some reason I am encountering a character encoding issue where "smart quotes" (’) are being displayed as black triangles with question marks (�), but only on the server.
This is on the HTML:
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
My local MySQL database (without character issues) is MySQL 5.7.26 with an InnoDB table with UTF8MB4 encoding and a table collation of utf8mb4-unicode-ci
My server MySQL database (with character issues) is MySQL 5.5.5-10.3.21 with an InnoDB table with UTF8MB4 encoding and a table collation of utf8mb4-unicode-ci
Perhaps there is a PHP setting somewhere I am missing?
Edit:
if I run this script on my computer is works perfectly, but if I run the same script on my server with the same data in the database, it give me the character encoding issue:
error_reporting(E_ALL);
include 'dbconfig.php';
$id = 19;
try {
$pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_TO_STRING);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$sql = $pdo->prepare("SELECT * FROM products WHERE id=:id");
$sql->execute(['id' => $id]);
var_dump ($sql->fetch());
while ($row = $sql->fetch()) {
$data[] = $row;
}
echo json_encode($data);
} catch(PDOException $e) {
//echo "Error: " . $e->getMessage();
echo "Database Error";
}
$conn = null;
(Since this clearly shows a PDO omission, I am reopening)
One-line change:
$pdo = new
PDO("mysql:host=$servername;dbname=$dbname;dbname=db;charset=utf8mb4'",
$username, $password);
References:
http://mysql.rjweb.org/doc.php/charcoll#php
Trouble with UTF-8 characters; what I see is not what I stored (Look especially for "black diamond".)
Related
How can i get arabic data from MSSQL database using ODBC connection?
It appears as ????.
I tried below listed solutions which are not working for me.
1) 'Name'=>iconv("unicode", "utf-8", $row["Name"]),
2) 'Name'=>iconv("Arabic_CI_AS", "utf-8", $row["Name"]),
3) mysql_query("SET NAMES utf8");
4) mysql_query('SET CHARACTER SET utf8');
5) <meta charset="UTF-8" />
6) 'Name'=>mb_convert_encoding($row["Name"], 'UTF-8', 'SJIS'),
Code snippet:
$customer_query="select serial,CR_ID,Name,Email,Customer_NameE from [CRM].[005_Customers_tbl]";
$query = odbc_exec($link,$customer_query);
$total_count=odbc_num_rows($query);
$json = array();
if($total_count>0){
while ($row = odbc_fetch_array($query)) {
$json[] = array('serial'=>$row['serial'],
'CR_ID'=>$row['CR_ID'],
'Name'=>$row["Name"],
'Email'=>$row['Email'],
'Customer_NameE'=>$row['Customer_NameE']);
}
}
$result['customer']=$json;
I know that it's achievable using change collation of table but it's not possible for this application due to some limitations.
Any other possibilities to achieve that ?
First you have to put below line
<meta charset="UCS-2"/>
and do casting in query like this
$var = "select CAST(Name as VARBINARY(150) as Name) form $table_name;
and then use this line for convert ??? text to arabic language.
$name = iconv('UCS-2LE','UTF-8',$name)
I have a problem, when I try to echo a cyrillic character, it return like ????
Here's code
<?
include('db.php');
$sql = "SELECT * FROM menu_items WHERE reference=1";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$rows = array();
while($row = $result->fetch_object()) {
$rows[] = json_encode($row);
}
$items = implode(',',$rows);
echo '['.$items.']';
}else {
echo "ERROR";
}
?>
Any idea?
Collation : utf8_general_ci
And db.php:
<?
$servername = "localhost";
$username = "test";
$password = "Conqwe333!";
$conn=mysqli_connect($servername,$username,$password,"test");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
?>
Worked after <? $conn->set_charset("utf8");?>
Add before your $sql
$conn->query('SET NAMES utf8');
You can read more about it here
Also you will need to set proper header for browser. You can do it by serveral ways for example in meta html tag or using header('Content-Type: text/html; charset=utf-8');
You should set collation per connection:
mysqli_set_charset
Also you can perform sql
SET NAMES utf8;
but it's not recommended
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "test");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* change character set to utf8 */
if (!$mysqli->set_charset("utf8")) {
printf("Error loading character set utf8: %s\n", $mysqli->error);
} else {
printf("Current character set: %s\n", $mysqli->character_set_name());
}
$mysqli->close();
I am assuming you are using Bulgarian and UTF8, same will work for Russian and other languages, just change "bg" to proper string.
I do not recommend you to use cp1251, because it breaks unexpectedly with apache mod_rewrite and other tools like this.
You need to do following checks:
Check if your database / table collation is some UTF8. It could be utf8_general_ci or Bulgarian - difference is minimal and is more sorting related. (utf8_general_ci is perfectly OK)
Check you have following statement executed right after connect - set names UTF8;. You can do $mysqli->query("set names utf8");
Make sure you have proper "tags". Here an example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang='bg' xml:lang='bg' xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Нов сайт :)</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
You can include UTF8 "BOM" on the html, but it works pretty well without it. I usually work without "BOM", and when I want to be 100% complaint, I create an include file bom.php that contain just the BOM symbol and include it prior HTML template in normal PHP way, e.g. include "bom.php".
Hope this helps, if not, please comment.
EDIT:
Someone suggested you must be sure if your data is properly stored in MySQL. Easiest way is to open PHP MySQL Admin. If Cyrillic is shown there, all is OK.
I think the issue is a step back, try to first encode the cyrillic characters correctly: How to encode cyrillic in mysql?
I've done everything I can think of, but special characters are not displaying correctly on this webpage.
For example, in the database it's:
But on the site it's:
Nouveaux R�alistes
Here's everything I've checked...
The database is set to UTF-8:
The page was written in NetBeans, with the document encoding set to UTF-8:
The page header declares UTF-8:
The meta charset is set to UTF-8:
I've even added the following line to my .htacess:
But there characters are still not displaying correctly, and I get the following error from the W3C Validator:
I feel like I've attempted everything, but it still won't work. (I've even tried htmlspecialchars and htmlentities in PHP, but the page doesn't even render!)
UPDATE
As requested, here is the code I'm using:
class Exhibition {
public $exhibitionDetails;
public function __construct(Database $db, $exhibitionID){
$this->_db = $db;
$params['ExhibitionID'] = $exhibitionID;
$STH = $this->_db->prepare("SELECT *
FROM Exhibition
INNER JOIN Schedule
ON Exhibition.ExhibitionID = Schedule.ExhibitionID
WHERE Schedule.Visible = 1
AND Exhibition.ExhibitionID = :ExhibitionID;");
$STH->execute($params);
$this->exhibitionDetails = $STH->fetchAll(PDO::FETCH_ASSOC);
}
}
And...
try {
$db = new Database(SITE_ROOT."/../");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$exhibition = new Exhibition($db,$_GET['id']);
} catch (PDOException $e) {
echo "<p class='error'>ERROR: ".$e->getMessage()."</p>";
}
And finally...
<p><?php echo $exhibition->exhibitionDetails[0]["Desc"]; ?></p>
If you are using mysql_* functions:
mysql_query("SET NAMES 'utf8'");
If you are using PDO
$dsn = 'mysql:host=localhost;dbname=testdb';
$username = 'username';
$password = 'password';
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$dbh = new PDO($dsn, $username, $password, $options);
It sets connection encoding.
It's been a few years since I've used PHP but back then it didn't natively support Unicode and a quick search of google tells me it still doesn't. You can still make it work though.
Here's a great link:
Encodings And Character Sets To Work With Text
This question already has answers here:
Whether to use "SET NAMES"
(3 answers)
Closed 9 years ago.
I have Japanese on my site coming from a mysql database.
Other Japanese text on the site displays fine, but the stuff coming out of the database looks like:
????????
The database is set to UTF8, so is the web page.
To fix the issue, before I make any calls to the database I use:
$db->query("SET NAMES utf8");
I was wondering if there was a better/easier way to do the above without having to set names before every query?
You don't have to use SET NAMES utf8 before every query, you just have to run it once the connection is established. Here's an example with PDO :
try {
$dns = "mysql:host={HOST};dbname={DB}";
$user = "{USER}";
$pass = "{PASS}";
$con = new PDO($dns, $user, $pass);
} catch ( Exception $e ) {
echo "Connexion error ", $e->getMessage();
die();
}
$con->query("SET NAMES utf8;");
//and now, as many queries as you want
If you're using PHP >= 5.3.6, you can define the charset in the connection string (prior PHP versions ignore it) :
try {
$dns = "mysql:host={HOST};dbname={DB};charset=utf8";
$user = "{USER}";
$pass = "{PASS}";
$con = new PDO($dns, $user, $pass);
} catch ( Exception $e ) {
echo "Connexion error ", $e->getMessage();
die();
}
//and now, as many queries as you want
This question already has answers here:
UTF-8 all the way through
(13 answers)
Closed 12 months ago.
I have a mysql table with contents
the structure is here:
I want to read and print the content of this table to html
This is my code:
<?php
include("config.php");
$global_dbh = mysql_connect($hostname, $username, $password)
or die("Could not connect to database");
mysql_select_db($db)
or die("Could not select database");
function display_db_query($query_string, $connection, $header_bool, $table_params) {
// perform the database query
$result_id = mysql_query($query_string, $connection)
or die("display_db_query:" . mysql_error());
// find out the number of columns in result
$column_count = mysql_num_fields($result_id)
or die("display_db_query:" . mysql_error());
// Here the table attributes from the $table_params variable are added
print("<TABLE $table_params >\n");
// optionally print a bold header at top of table
if($header_bool) {
print("<TR>");
for($column_num = 0; $column_num < $column_count; $column_num++) {
$field_name = mysql_field_name($result_id, $column_num);
print("<TH>$field_name</TH>");
}
print("</TR>\n");
}
// print the body of the table
while($row = mysql_fetch_row($result_id)) {
print("<TR ALIGN=LEFT VALIGN=TOP>");
for($column_num = 0; $column_num < $column_count; $column_num++) {
print("<TD>$row[$column_num]</TD>\n");
}
print("</TR>\n");
}
print("</TABLE>\n");
}
function display_db_table($tablename, $connection, $header_bool, $table_params) {
$query_string = "SELECT * FROM $tablename";
display_db_query($query_string, $connection,
$header_bool, $table_params);
}
?>
<HTML><HEAD><TITLE>Displaying a MySQL table</TITLE></HEAD>
<BODY>
<TABLE><TR><TD>
<?php
//In this example the table name to be displayed is static, but it could be taken from a form
$table = "submits";
display_db_table($table, $global_dbh,
TRUE, "border='2'");
?>
</TD></TR></TABLE></BODY></HTML>
but I get ???????? as the results:
Where is my mistake?
Four good steps to always get correctly encoded UTF-8 text:
1) Run this query before any other query:
mysql_query("set names 'utf8'");
2) Add this to your HTML head:
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
3) Add this at top of your PHP code:
header("Content-Type: text/html;charset=UTF-8");
4) Save your file with UTF-8 without BOM encoding using Notepad++ or any other good text-editor / IDE.
Set the charset as utf8 as follows:
$conn = new mysqli($servername, $username, $password, $dbname);
$conn->set_charset("utf8");
You are not defining your HTML page as UTF-8. See this question on ways to do that.
You may also need to set your database connection explicitly to UTF8. Doing a
mysql_query("SET NAMES utf8;");
^
Put it right under your database connection script or include and MAKE sure you have it placed before you do any necessary queries. Also, for collocation please take the time to make sure your
setting it for your proper syntax type and general_ci seems working good for me when used. As a finale, clear your cache after banging your head, set your browser to proper encoding toolbar->view->encoding
Setting the connection to UTF8 after establishing the connection takes care of the problem. Don't do this if the first step already works.
UTF-8 content from MySQL table with PDO
To correctly get latin characters and so on from a MySQL table with PDO,
there is an hidden info coming from a "User Contributed Note" in the PHP manual website
(the crazy thing is that originally, that contribution was downvoted, now luckily turned to positive .. sometime some people need to got blamed)
my credits credits go to this article that pulled the solution and probably made that "User Contributed Note" to turn positive
If you want to have a clean database connection with correct Unicode characters
$this->dbh = new PDO(
"mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=utf8",
DB_USER,
DB_PASS);
try this :
mysql_set_charset('utf8', $yourConnection);
Old ways have been deprecated. If you are using PHP > 5.0.5 and using mysqli the new syntax is now:
$connection->set_charset("utf8")
Where $connection is a reference to your connection to the DB.
I tried several solutions but the only one that worked
is that of Hari Dass:
$conn->set_charset("utf8");