PHP / MySQL中的PDO和UTF-8特殊字符?
Posted
技术标签:
【中文标题】PHP / MySQL中的PDO和UTF-8特殊字符?【英文标题】:PDO and UTF-8 special characters in PHP / MySQL? 【发布时间】:2011-12-21 14:46:40 【问题描述】:我正在使用 mysql 和 php 5.3 并尝试了此代码。
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = '';
$con = mysql_connect("localhost", "root", "");
mysql_set_charset('utf8');
if (!$con)
die('Could not connect: ' . mysql_error());
mysql_select_db("kdict", $con);
$sql = "SELECT * FROM `en-kh` where english='a'";
echo $sql;
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
echo $row['english'] . " </br> " . $row['khmer'];
echo "<br />";
?>
=> 我的 UTF-8 渲染显示效果很好,做得很好。
但现在我创建了一个 PDO 类来保持易于扩展和更简单
class crud
// code..
public function conn()
isset($this->username);
isset($this->password);
if (!$this->db instanceof PDO)
$this->db = new PDO($this->dsn, $this->username, $this->password);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
/*more code here*/
/*** a new crud object ***/
$crud = new crud();
/*** The DSN ***/
$crud->dsn = "mysql:dbname=kdict;host=localhost";
/*** MySQL username and password ***/
$crud->username = 'root';
$crud->password = '';
/*** select all records from table ***/
$records = $crud->rawSelect("SELECT * FROM `en-kh` where english='a'");
/*** fetch only associative array of values ***/
$rows = $records->fetchAll(PDO::FETCH_ASSOC);
/*** display the records ***/
foreach($rows as $row)
foreach($row as $fieldname=>$value)
echo $fieldname.' = '.$value.'<br />';
echo '<hr />';
?>
但它显示我的角色是这样的'????'
我在 Stack Overflow 上找到了这个链接,看起来和我遇到的问题一样 Special characters in PHP / MySQL
它看起来和我的问题一样 => 我试图修复它,但还是不行。
$this->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAME'utf8'");
谁能告诉我问题是什么?我该如何纠正?
谢谢
【问题讨论】:
您存储所述数据的表的default charset
是什么?
嗯,我只使用过 UTF8,但发现这篇文章很有趣:***.com/questions/2344118/utf-8-general-bin-unicode。根据 Alix 的帖子,也许也可以尝试将您的数据库连接设置为 utf_unicode_ci
。
感谢您的信息@Digital Precision
【参考方案1】:
我建议始终通过 PDO 连接到数据库。
下面是示例代码;
<?php
class connMysql
protected static $instance;
private static $database_type = "mysql";
private static $hostname = "localhost";
private static $user = “database_user”;
private static $password = “database_user_password”;
private static $database_name = “your_database”;
private static $persistent = false;
private function __construct()
try
self::$instance = new \PDO(self::$database_type . ":host=" . self::$hostname . ";dbname=" . self::$database_name
, self::$user
, self::$password
, array(
\PDO::ATTR_PERSISTENT => self::$persistent,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_STRINGIFY_FETCHES => true,
\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"
));
catch (PDOException $e)
echo "Connection Error: " . $e->getMessage();
public static function getInstance()
if (!self::$instance)
new connMysql();
return self::$instance;
public static function close()
self::$instance = null;
【讨论】:
【参考方案2】:使用 PDO 插入特殊字符的可能方法,只需按照以下步骤操作:
1) 将属性设置为您的连接类。
$this->db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAME'utf8'");
2) 现在您可以在查询创建和插入数据库时使用 htmlspecialchars:
$ShortDescription = htmlspecialchars($_POST['ShortDescription'], ENT_QUOTES);
$LongDescription = htmlspecialchars($_POST['LongDescription'],ENT_QUOTES);
它会正常工作的。
【讨论】:
【参考方案3】:我遇到了同样的麻烦,在尝试了 1000000 个不同的选项后发现默认的 mysql 引擎仍然是 MyISAM。
验证 InnoDB 是否是默认存储引擎:
发出命令SHOW VARIABLES LIKE 'have_innodb';
以确认 InnoDB 完全可用。
然后发出命令SHOW ENGINES;
以查看所有不同的 MySQL 存储引擎。
在InnoDB
行而不是MyISAM
行中查找DEFAULT
。我意识到我提供的设置阻止我使用SET storage_engine=MYISAM;
更改默认引擎。就我而言,我联系了我的提供商并被引导到我可以更改选项以更改默认引擎的位置。希望这会有所帮助!
【讨论】:
【参考方案4】:您缺少一个 S:it's SET NAMES
而不是 SET NAME
:
$this->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
当然,您还需要取消注释。 另外,在您建立数据库连接后,PDO::MYSQL_ATTR_INIT_COMMAND
can not be set 和 PDO::setAttribute()
(常量名称说明了一切),您必须使用 $driver_options
参数在 constructor 中指定它,如下所示:
$this->db = new PDO($this->dsn, $this->username, $this->password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
另一种方法是在连接后立即执行相同的查询:
$this->db = new PDO($this->dsn, $this->username, $this->password);
$this->db->exec("SET NAMES 'utf8';");
【讨论】:
@Transformer:关于这一点我不知道,它根据文档存在(请参阅php.net/manual/en/ref.pdo-mysql.php)并且我以前使用过它......也许你有一个过时的 PDO 版本?有关可能的解决方法,请参阅我的答案更新。 谢谢@Alix Axel 与 option1 使用 $driver_options 它对我不起作用。我不知道我错了什么,但是对于 Option2 $this->db->exec("SET名称'utf8';"); ==> 它有效。非常感谢!:) 这对我有用 $this->db->exec("SET NAMES 'utf8';"); 在尝试之前,$this->db = new PDO($this->dsn, $this->username, $this->password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES ' utf8'"));我一直用 php 函数进行 utf8_encoding 和 utf8_decoding,真的很烂! 你知道 SQL server 也一样吗?以上是关于PHP / MySQL中的PDO和UTF-8特殊字符?的主要内容,如果未能解决你的问题,请参考以下文章
php中的Mysqlnd、PDO和PDO_Mysql扩展有啥区别?
使用 PDO 和 PHP 将表单中的数据插入 MySQL 数据库