Today I got an error while I was developing an app based on PHP, MySql and the Zend Framework. Moreover, I'm using phpseclib to encrypt the data using the AES algorithm and here came the problem. The output of the AES algorithm is in a form that seems MySql doesn't like. Infact when I try to insert the data into the database a got an Sql Exception. The error is:
SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xE4\xD5\xABtZM...' for column 'Name'
I've already read all the answers posted on Stackoverflow and have also Googled the problem but all the proposed solution were already in my code. Database, tables and all the cols have Collation utf8_general_ci
. Below you can see the relevant code:
application.ini
resources.db.adapter = "Pdo_Mysql"
resources.db.params.charset = "utf8"
resources.db.params.host = "localhost"
resources.db.params.username = "********"
resources.db.params.password = "********"
resources.db.params.dbname = "dbname"
database.php
public static function getDb()
{
if (self::$Db === NULL)
self::$Db = Zend_Db_Table::getDefaultAdapter();
return self::$Db;
}
model.php
$Values = array(
'Id' => $this->Id,
'Name' => $this->Name,
'CreationDate' => $this->CreationDate,
);
$RowChanged = $Db->insert('TABLENAME', $Values);
encrypt()
public static function encrypt($Data, $EncryptionKey)
{
$AES = new Crypt_AES();
$AES->setKey($EncryptionKey);
return $AES->encrypt($Data);
}
table
CREATE TABLE IF NOT EXISTS `table` (
`Id` mediumint(8) unsigned NOT NULL,
`Name` varchar(200) DEFAULT NULL,
`CreationDate` date NOT NULL,
PRIMARY KEY (`Id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Question: How can I solve the problem and store the data into the database?
To conclude, the ERROR 1366: Incorrect string value happens when MySQL can't insert the value you specified into the table because of incompatible encoding. You need to modify or remove characters that have 4-bytes UTF-8 encoding, or you can change the encoding and collation used by MySQL.
The difference between utf8 and utf8mb4 is that the former can only store 3 byte characters, while the latter can store 4 byte characters. In Unicode terms, utf8 can only store characters in the Basic Multilingual Plane, while utf8mb4 can store any Unicode character.
MySQL supports multiple Unicode character sets: utf8mb4 : A UTF-8 encoding of the Unicode character set using one to four bytes per character.
I realize that this is a reference for AES_ENCRYPT for MySQL, however it looks like you may need to change your varchar(200)
to a varbinary(200)
(or larger) as AES seems to return a binary string.
There is a less clear explanation on the MySQL site.
Many encryption and compression functions return strings for which the result might contain arbitrary byte values. If you want to store these results, use a column with a VARBINARY or BLOB binary string data type. This will avoid potential problems with trailing space removal or character set conversion that would change data values, such as may occur if you use a nonbinary string data type (CHAR, VARCHAR, TEXT).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With