PDO cutting off strings at a UTF-8 character [duplicate] - php

This question already has answers here:
UTF-8 all the way through
(13 answers)
Closed 8 years ago.
I am using PHP 5.5 and when I attempt to insert a UTF-8 character in the MySQL database PDO cuts it off at the first non-ASCII character.
I have set my connection to be:
(DB_TYPE.':host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8', DB_USER, DB_PASS, array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING))
I have tried the SET NAMES that everyone posts, but that doesn’t work either because the problem is NOT on the MySQL side of things.
When I do an insert through phpMyAdmin and directly from the MySQL console, it works!
When I select the accented string with PDO, it works!
The problem is only on INSERT and UPDATE using PDO specifically!
Here is the SQL of the table. It is all in UTF-8 but maybe someone knows of a conflict between a setting and PDO
CREATE TABLE IF NOT EXISTS `mytable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_lang` int(11) NOT NULL DEFAULT '2',
`id_tgroup_cat` int(11) NOT NULL,
`fieldfor` int(11) NOT NULL,
`colors` varchar(100) NOT NULL,
`text` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=34 ;
I have already tried to make text a varchar field and that did not change anything.
The actual insert in PHP:
$query = $this->db->prepare("UPDATE mytable
SET text = ?,
colors = ?
WHERE id = ?");
$query->execute(array($text, $colors, $id));
Where $text = "référence" (only saves the letter R in the database but without accents it saves everything) and $colors is an empty string for test purposes and $id is 2.

This is the key clue to me:
Where $text = "référence" (only saves the letter R in the database but
without accents it saves everything) and $colors is an empty string
for test purposes and $id is 2.
Sounds like it is a UTF-8 encoding issue. While the database is UTF-8 the whole chain from the code to the database—including the connection—should be UTF-8 clean.
How exactly does $this->db->prepare relate to the PHP connection to MySQL? A bit unclear from the code you have shown. But based on what you are showing, perhaps adjusting your query like this would help:
$query = $this->db->prepare("SET collation_connection = utf8_bin;
SET NAMES utf8;
UPDATE mytable
SET text = ?,
colors = ?
WHERE id = ?");
Or maybe this:
$this->db->exec("SET collation_connection = utf8_bin; SET NAMES utf8;");
$query = $this->db->prepare("UPDATE mytable
SET text = ?,
colors = ?
WHERE id = ?");
Note my forced-in addition of SET collation_connection = utf8_bin; as well as SET NAMES utf8;
In general you need to make sure your entire chain from the connection, to the database, to the tables is all UTF8 clean. I have a detailed answer to a similar question here.
But in your case, check the actual MySQL server my.cnf file. The following would set the whole chain to UTF-8:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
EDIT: And since the original poster indicates the data is coming from an HTML5 form, I also think checking the BOM (byte order mark) for the actual HTML5 file itself would help as well. It should be set to UTF8. More details on what a BOM is are over here. Specifically the accepted answer from Martin Code which explains:
The UTF-8 BOM is a sequence of bytes (EF BB BF) that allows the reader
to identify the file as an UTF-8 file.

Related

Save Japanese characters into MySQL

I am using PHP for executing a MySQL update sentence with Spanish, English and Japanese characters.
But i'm not able to save Japanese characters into the database. How should I proceed?
Database has utf8_general_ci collation.
$strSQL = "UPDATE table SET value = '" . addslashes($strValue) . "'";
$strSQL = utf8_decode($strSQL);
mysqli_query($cnn, $strSQL);
With addslashes I can get apostrophes to be saved into the database.
With utf8_decode I can get Spanish characters to be saved into the database.
Why you proccess utf8_decode() the sql query?
Look at http://php.net/manual/en/function.utf8-decode.php for details about utf8_decode()
You have to check a few things.
Whether there is a problem in your database and tables Or in your PHP script.
 
 
Database :
CREATE DATABASE test DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
Table Charset :
CREATE TABLE test.table
(
id INT NOT NULL AUTO_INCREMENT,
text VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = MyISAM;
Connection :
SET NAMES utf8;
E.g :
$mysqli = new mysqli("localhost","my_user","my_password","test_db");
$mysqli->set_charset("utf8");
OR
$link = mysqli_connect("localhost","my_user","my_password","test_db");
mysqli_set_charset($link,"utf8");
Configure the encoding charset of server :
With PHPMyAdmin , Choose UTF-8 when you login.
PHP Script :
header('Content-Type: text/html;charset=UTF-8');
Apache Config (/etc/httpd/conf/httpd.conf) :
AddDefaultCharset UTF-8
Apache .htaccess file :
AddCharset UTF-8 .htm
AddCharset UTF-8 .html
AddCharset UTF-8 .php
PHP Config (/etc/php.ini) :
default_charset = "utf-8"
MySQL Config (/etc/my.cnf ) :
[client]
default-character-set=utf8
[mysqld]
default-collation=utf8_unicode_ci
character-set-server=utf8
default-character-set=utf8
init-connect='SET NAMES utf8'
character-set-client = utf8
User values :
e.g : $_GET , $_POST
You can use mb_convert_encoding() for convert your strings to UTF-8.
Useful Links :
PHP inserting Japanese string to utf8 table as something else, but still reads it successfully
http://es2.php.net/manual/en/mysqli.set-charset.php
Select MySQL rows with Japanese characters
http://php.net/manual/en/function.mysql-set-charset.php
https://www.w3schools.com/php/func_mysqli_set_charset.asp
PHP mysql charset utf8 problems
https://medium.com/#adamhooper/in-mysql-never-use-utf8-use-utf8mb4-11761243e434
https://dev.mysql.com/doc/refman/8.0/en/faqs-cjk.html
https://www.experts-exchange.com/questions/24742133/How-to-insert-a-japanese-character-into-mysql-database.html

How to fix LAMP UTF8 encoding? [duplicate]

This question already has answers here:
UTF-8 all the way through
(13 answers)
Closed 9 years ago.
I set all about encoding to utf8. but browser show me '???????'. My settings are below.
MySQL "show variables like 'c%'"
character_set_client | utf8
character_set_connection | utf8
character_set_database | utf8
.... (all utf8)
MySQL my.cnf
[client]
default-character-set = utf8
[mysqld]
init_connect="SET collation_connection = utf8_general_ci"
init_connect="SET names utf8"
character-set-server = utf8
collation-server = utf8_general_ci
[mysql]
default-character-set = utf8
In all my PHP file included:
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
Apache2 httpd.conf
AddDefaultCharset Off (if utf-8, show me '???' ,too)
In MySQL console, (database is dumped)
SELECT name from campagin LIMIT 1
=> print in working order, not '????'
I don't know what is problem.
For reference, I test this case.. in test.php
<?php
mysql_connect('localhost','root',ROOT_PW);
mysql_select_db(TEST_DB_NAME);
mysql_query("INSERT INTO a SET msg='안녕하세요'"); // char is KOREAN, meaning 'Hi'
$res = mysql_query("SELECT msg FROM a LIMIT 1");
$row = mysql_fetch_assoc($res);
echo $row['msg'];
?>
=> this print '안녕하세요' in working order not '????'
but in MySQL console
"SELECT msg FROM a LIMIT 1"
=> print not '안녕하세요' but abnormally '안녕하세요'
ADDED :
in mysql console
"SHOW CREATE TABLE a"
=> Table | Create Table
a | CREATE TABLE `a` ( 'msg' varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8
Using the base mysql_ connector you will need to declare
mysql_query( "SET NAMES utf8" );
mysql_query( "SET CHARACTER SET utf8" );
These tell MySQL that your communications with it are going to be via UTF8, otherwise it may not work.
Further more you need to make certain your tables and their columns are defined UTF-8, MySQL handles encoding at a column level. if you SHOW CREATE TABLE campagin what do you get for encoding on the table and columns? If a column doesn't spit out an encoding, it will default to the table level encoding.

What may cause question marks instead of non-ASCII symbols?

Can't figure out why is it happening, there is definitely something wrong with the enviroment.
I have db declared as
CREATE DATABASE `mydb` /*!40100 DEFAULT CHARACTER SET latin1 */
Then I have a table declared as
CREATE TABLE `myabstract_table` (
`key_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`varchar_field` varchar(128) NOT NULL
PRIMARY KEY (`key_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Then I have usual for this case php code:
function execSQL($conn, $sql, $values = false) {
try {
$stmt = $conn->prepare($sql);
if ($values)
foreach($values as $param=>$value)
$stmt->bindValue($param, $value);
if ( ! $stmt->execute() ) {
error_log ("PDO Error: ".json_encode($stmt->errorInfo()));
return false;
}
} catch (PDOException $e) {
error_log ("Exception: " . $e->getMessage());
return false;
}
return $stmt;
}
and after that the strings are saving (via INSERT statement) to db with question marks instead of non-ASCII symbols
PS. I perform set names 'utf8' before any sql request, all php stuff is cofigured for UTF-8, html document header contains meta tag with UTF-8 secified as charset;
the only thing I didn't try is to change default charset of schema itself (it's currently latin1) since I'm pretty sure it's not at issue. Or is it?
OK, I've found the reason. There was another bit I forgot to mention. It's stored procedure. This procedure was inserting rows not usual INSERT right from php.
I think, default schema charset affects procedure IN varchars parameter declared without explicit charset. I've finally done the following:
CREATE PROCEDURE `sp_myabstract_proc`(
`prm_key_id` int(10),
`prm_varchar_param` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci
)
BEGIN
-- some insert logic here
END;
(CHARACTER SET utf8 option made the trick)
So in my case mysql engine was dealing with prm_varchar_param as with latin1 inherited from schema attribute.
You need to change the character set of the database to UTF-8 or a character set for Cyrillic characters.
Latin-1 can't encode Cyrillic characters and that's why they're appearing as question marks in the database.
edit: I just saw you're declaring the table with UTF-8 character set, so I'm stumped.

php mysql search with special character

I have a table in mysql DB which contains special character like Ø,Æ,etc. I cannot find these fields when i run a search with php. but when i run the same sql in phpmyadmin, i get results.
this is the table structure:
CREATE TABLE IF NOT EXISTS `clientinfo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`adresse` varchar(160) NOT NULL,
`gatenavn` varchar(20) NOT NULL,
`husnr` varchar(20) NOT NULL,
`bokstav` varchar(2) NOT NULL,
`postnr` varchar(20) NOT NULL,
`poststed` varchar(60) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=398 ;
This is a sample query:
SELECT * FROM clientinfo WHERE gatenavn = 'EKRAVEIEN' AND husnr = '1' AND postnr = '2010' AND poststed = 'STRØMMEN'
when i run this query in phpmyadmin, i get result; but don't get when i run with php. I am using mysqli. need some help.
Tell your connection instance, to deliver UTF-8, before making queries. In MySqli you can call the function set_charset(), afterwards the connection object will deliver UTF-8.
Calling this function makes you independent of the database configuration, if necessary the connection will convert the returned data. Of course it is fastest if no conversion is necessary, so adjusting the configuration is a good thing too.
// tells the mysqli connection to deliver UTF-8 encoded strings.
$db = new mysqli($dbHost, $dbUser, $dbPassword, $dbName);
$db->set_charset('utf8');
Try setting :
SET NAMES utf8;
before your query in the same mysql session
If you have access to your MySQL configuration file, set these settings to my.cfg:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
Try using htmlspecialchars php function.
string htmlspecialchars ( string $string , int $flags = ENT_COMPAT | ENT_HTML401
, string $encoding = 'UTF-8' , bool $double_encode = true)
You can change the encoding info of your string. Eg KOI8-R for Russian symbols
This could be a issue with your php.ini file, your Apache Webserver, or charset of your HTML Document or your MySQL
Couple of things to to:
Always ensure that your charset is set to utf8 in your html meta tags
Set
default_charset = "utf-8";
in your php.ini file
And add
AddDefaultCharset UTF-8
to your httpd.conf if you are outputting unicode chars

Can't insert cyrillic text into mysql database

When I'm trying to insert cyrillic text into MySQL database it inserts it like:
г???????????? ?? ????????
Рісѓрїр°ріс‹рї р° с‹рір°рї
So, I have two pages: registration.php and addUser.php. In each of them
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Database consist of 11 tables, each table has collation: utf8_general_ci, type: MyISAM. Each field in every table has Collation: utf8_general_ci.
When I'm writing to database directly in phpMyAdmin and then show this data to web-page. In English and Russian - all OK.
But when I'm full my form with personal data on registration.php and then going to addUser.php - all cyrillic characters displayed like I wrote upper - on page and in database too.
function AddNewUser($Name, $Surname, $FatherName, $Email, $Password, $Phone, $DegreeID, $RankID,
$Organization, $Department, $Country, $City, $Address, $Job)
{
//fetch data from database for dropdown lists
//connect to db or die)
$db = mysql_connect($GLOBALS["gl_kussdbName"], $GLOBALS["gl_kussUserName"], $GLOBALS["gl_kussPassword"] ) or die ("Unable to connect");
//to prevenr ????? symbols in unicode - utf-8 coding
mysql_query("SET NAMES 'UTF8'");
//select database
mysql_select_db($GLOBALS["gl_kussDatabase"], $db);
$sql = "INSERT INTO UserDetails (
UserFirstName,
UserLastName,
UserFatherName,
UserEmail,
UserPassword,
UserPhone,
UserAcadDegreeID,
UserAcadRankID,
UserOrganization,
UserDepartment,
UserCountry,
UserCity,
UserAddress,
UserPosition)
VALUES(
'".$Name."',
'".$Surname."',
'".$FatherName."',
'".$Email."',
'".$Password."',
'".$Phone."',
'".$DegreeID."',
'".$RankID."',
'".$Organization."',
'".$Department."',
'".$Country."',
'".$City."',
'".$Address."',
'".$Job."'
);";
//execute SQL-query
$result = mysql_query($sql, $db);
if (!$result)
{
die('Invalid query: ' . mysql_error());
}
//close database = very inportant
mysql_close($db);
}
?>
There also such information in phpMyAdmin:
auto increment increment 1
auto increment offset 1
autocommit ON
automatic sp privileges ON
back log 50
basedir \usr\local\mysql-5.1\
big tables OFF
binlog cache size 32,768
binlog format STATEMENT
bulk insert buffer size 8,388,608
character set client utf8
(Global value) cp1251
character set connection utf8
(Global value) cp1251
character set database cp1251
character set filesystem binary
character set results utf8
(Global value) cp1251
character set server cp1251
character set system utf8
character sets dir \usr\local\mysql-5.1\share\charsets\
collation connection utf8_general_ci
(Global value) cp1251_general_ci
collation database cp1251_general_ci
collation server cp1251_general_ci
completion type 0
concurrent insert 1
So I need to properly show, save and select russian text from database. Thanx!
connect timeout 10
datadir \usr\local\mysql-5.1\data\
Try calling mysql_set_charset('utf8'); after connecting to the database. I think it's similar to executing a SET NAMES query, but since the PHP manual says using that function over a SET NAMES query is recommended, I'd try it.
Also, when you display your content, you could try echo htmlentities($string, ENT_COMPAT, 'UTF-8');
I store greek in tables created like ths:
CREATE TABLE `test` (
`test_id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
`test_name` VARCHAR(30) NOT NULL,
PRIMARY KEY (`test_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
Or if table already created I guess you can change the charset it in the phpmyadmin interface. Maybe this helps.
Check your MySQL configuration and ensure that your encoding is defined correctly.
Add these lines to my.cnf or my.ini, which ever your installation uses.
These settings did the trick for me:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
character-set-server=utf8
I have tried multiple collations in phpMyAdmin as well as changing the charset of the page, which didn;t make sense but i was willing to try anything after two days of research. this command helped me: mysql_set_charset('utf8');
Collation on the column was set to koi8r_general_ci
Edit your structure field to set collation utf16_general_ci.
After that insert your data.

Categories