什么可能导致问号而不是非ASCII符号?

时间:2013-07-03 09:19:14

标签: php mysql character-encoding pdo

无法弄清楚为什么会发生这种情况,环境肯定存在问题。 我将db声明为

CREATE DATABASE `mydb` /*!40100 DEFAULT CHARACTER SET latin1 */

然后我有一个声明为

的表
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;

然后我通常会遇到这种情况的PHP代码:

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;
}

之后,字符串将(通过INSERT语句)保存到带有问号而不是非ASCII符号的数据库

PS。我在任何sql请求之前执行set names 'utf8',所有php的东西都是为UTF-8配置的,html文档头包含带有UTF-8的元标记,并将其作为charset; 我唯一没有尝试的是更改架构本身的默认字符集(它目前是latin1),因为我很确定它不是问题。或者是吗?

enter image description here

2 个答案:

答案 0 :(得分:2)

好的,我找到了原因。还有一点我忘了提及。这是存储过程。这个过程是直接从php插入行而不是通常的INSERT。

我认为,默认模式字符集会影响在没有显式字符集的情况下声明的过程IN varchars参数。我终于完成了以下工作:

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选项成功了) 所以在我的情况下,mysql引擎正在处理prm_varchar_param,就像继承自schema属性的latin1一样。

答案 1 :(得分:0)

您需要将数据库的字符集更改为UTF-8或Cyrillic characters的字符集。

Latin-1无法对西里尔字符进行编码,这就是为什么它们会在数据库中显示为问号。

编辑:我刚看到你用UTF-8字符集声明表格,所以我很难过。