PHP PDO:字符集,集合名称?
我以前在正常的mysql_*连接中使用过:PHP PDO:字符集,集合名称?,php,mysql,pdo,Php,Mysql,Pdo,我以前在正常的mysql_*连接中使用过: mysql_set_charset("utf8",$link); mysql_query("SET NAMES 'UTF8'"); PDO需要它吗?我应该把它放在哪里 $connect = new PDO("mysql:host=$host;dbname=$db", $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); 您将在连接字符串中包含它,如: "mysql
mysql_set_charset("utf8",$link);
mysql_query("SET NAMES 'UTF8'");
PDO需要它吗?我应该把它放在哪里
$connect = new PDO("mysql:host=$host;dbname=$db", $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
您将在连接字符串中包含它,如:
"mysql:host=$host;dbname=$db;charset=utf8"
但是,在PHP5.3.6之前,字符集选项被忽略。如果您运行的是旧版本的PHP,则必须按照以下方式执行:
$dbh = new PDO("mysql:$connstr", $user, $password);
$dbh->exec("set names utf8");
<?php
$dbh = new PDO("mysql:$connstr", $user, $password);
$dbh -> exec("set names utf8");
?>
我认为您需要另外一个查询,因为DSN中的字符集选项实际上被忽略了。参见另一个答案评论中的链接 看看Drupal 7是如何在中实现的:
在PHP5.3.6之前,字符集选项被忽略。如果您运行的是旧版本的PHP,则必须按照以下方式执行:
$dbh = new PDO("mysql:$connstr", $user, $password);
$dbh->exec("set names utf8");
<?php
$dbh = new PDO("mysql:$connstr", $user, $password);
$dbh -> exec("set names utf8");
?>
这可能是最优雅的方式。
就在PDO构造函数调用中,但要避免错误的字符集选项(如上所述):
非常适合我。为了完整起见,当从PDO连接到MySQL时,实际上有三种方法可以设置编码,哪些方法可用取决于您的PHP版本。优先顺序为:
charset
参数PDO::MYSQL\u ATTR\u INIT\u命令运行SET NAMES utf8
设置名称utf8
<?php
define('DB_HOST', 'localhost');
define('DB_SCHEMA', 'test');
define('DB_USER', 'test');
define('DB_PASSWORD', 'test');
define('DB_ENCODING', 'utf8');
$dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_SCHEMA;
$options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
if( version_compare(PHP_VERSION, '5.3.6', '<') ){
if( defined('PDO::MYSQL_ATTR_INIT_COMMAND') ){
$options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . DB_ENCODING;
}
}else{
$dsn .= ';charset=' . DB_ENCODING;
}
$conn = @new PDO($dsn, DB_USER, DB_PASSWORD, $options);
if( version_compare(PHP_VERSION, '5.3.6', '<') && !defined('PDO::MYSQL_ATTR_INIT_COMMAND') ){
$sql = 'SET NAMES ' . DB_ENCODING;
$conn->exec($sql);
}
我只想补充一点,您必须确保您的数据库是使用COLLATUTF8\u general\u ci或您想要使用的任何排序规则创建的,否则您可能会得到另一个超出预期的排序规则
在phpmyadmin中,您可以通过单击数据库并选择操作来查看排序规则。如果尝试使用数据库以外的其他排序规则创建表,则表最终将使用数据库排序规则
因此,在创建表之前,请确保数据库的排序规则正确。希望这能节省一些时间lol我测试了这段代码并
$con="";
$MODE="";
$dbhost = "localhost";
$dbuser = "root";
$dbpassword = "";
$database = "name";
$con = new PDO ( "mysql:host=$dbhost;dbname=$database", "$dbuser", "$dbpassword", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$con->setAttribute ( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$db=new PDO('mysql:host=localhost;dbname=cwDB','root','',
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$sql="select * from products ";
$stmt=$db->prepare($sql);
$stmt->execute();
while($result=$stmt->fetch(PDO::FETCH_ASSOC)){
$id=$result['id'];
}
在我的情况下,我必须添加这一行:
$conn->exec("set names utf8"); //Support utf8
它将是什么样子:
$conn = new PDO("mysql:host=$servername;dbname=$db", $username, $password);
$conn->exec("set names utf8"); //Support utf8
值得注意的是,这种行为在5.3.6中发生了变化,现在工作正常。应该是UTF-8的utf8 instaead“mysql:host=$host;dbname=$db;charset=utf8”如果您使用的是最新版本的PHP,请忽略下面的答案:它在PHP5.3.8中工作正常。在这种情况下,我还需要指定排序规则吗?例如“SET NAMES utf8 COLLATE utf8\u unicode\u ci”?从utf8切换到utf8mb4。我的理解是,这对于PHP5.3.0来说也是一个错误。在这种情况下,您需要通过引用其编号而不是名称在数组中输入选项,如下所示:array(1002=>'SET NAMES utf8',…)
。感谢您的提示!我在运行不同5.3.X版本PHP的多个生产系统上成功地使用了上述代码,但实际上没有一个是5.3.0。我认为如果没有特定于数据库的选项,它可能会更优雅。MYSQL\u ATTR\u INIT\u命令仅适用于MYSQL数据库(有关每种db类型的可用命令,请参阅的子页)。但这正是OP所要求的。在dsn字符串中传递charset=utf8
是有效的!我试图在“SET NAMES utf8”中找出问题所在应避免使用,因为SQL注入。有关详细信息,请参阅。如果您有字符集问题,则您可能别无选择,只能设置为utf8。我认为应该使用以下命令。使用PDO::prepare使用绑定参数准备SQL语句。@Masakelastic,那么我们应该如何将排序规则指定为“集合名称utf8校对utf8\U unicode\U ci”"mods注意:这是正确的答案,在被接受的答案将此信息编辑到其中一年前发布。是否有ODBC/Access等效项?我现在有一个可以工作的Oracle和MySQL PHP PDO UTF8连接,但我无法让它在ODBC/Access中工作。哦,而且从未定义您的数据库密码。它们与超级全局一样全局s、 当您使用密码时,这不是一件好事。“如果您尝试使用数据库以外的其他排序规则创建表,那么您的表最终将使用数据库排序规则”-我认为这是不正确的。表排序优先于数据库排序。虽然此代码可能回答此问题,但提供有关此代码为什么和/或如何回答此问题的其他上下文可提高其长期价值。虽然此答案可能是正确和有用的,但最好包含一些解释这在将来特别有用,如果有变化(可能无关)导致它停止工作,并且用户需要了解它曾经是如何工作的。
$conn = new PDO("mysql:host=$servername;dbname=$db", $username, $password);
$conn->exec("set names utf8"); //Support utf8