Mysql: General error: 1366 Incorrect string value

2019-04-19 19:45发布

问题:

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:

  1. Application.ini to see how is set up the connection
  2. Database.php to see how I retrieve the database connection
  3. Model.php to see how I try to insert the data in the database
  4. encrypt() to see how I use the AES class to encrypt the data
  5. Table definition (If know that all are in utf8 isn't enough)

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?

回答1:

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).