Невозможно извлечь символы с ударением UTF-8 из доступа через PDO ODBC


Я пытаюсь получить доступ к БД, преобразованной в MySQL. Все работает отлично, рассчитывайте на один большой разводной ключ... Если БД доступа имеет какие-либо нестандартные символы, он не будет работать. Мой запрос скажет мне:

Incorrect string value: 'xE9d'

Если я непосредственно эхо из текста строк, который имеет "недопустимый" символ, я получаю знак вопроса в Черном квадрате в моем браузере (так что é превратится в этот недопустимый символ на echo).

Примечание: то же самое От будет принимать, сохранять и отображать "é" штраф в текстовом поле это используется для заголовка этой загрузки БД. Кроме того, если я "сохраняю как" страницу и снова открываю ее, " é " отображается правильно....

Вот как я соединяюсь:

$conn = new PDO("odbc:Driver={Microsoft Access Driver (*.mdb)};Dbq=$fileLocation;SystemDB=$securefilePath;Uid=developer;Pwd=pass;charset=utf;");

Я перепробовал множество вещей, в том числе:

$conn -> exec("set names utf8");

Когда я пробую ' CurrentDb.CollatingOrder ' в access он говорит мне 1033 очевидно, что dbSortGeneral для "английского, немецкого, французского и португальского порядка сортировки".

Что случилось? Это почти как PDO посылает мне параметры сортировки мой браузер и PHP делает не совсем понимаю.

1 2

1 ответ:

Проблема

При использовании собственных функций PHP ODBC (PDO_ODBC или более старых функций odbc_) и драйвера Access ODBC текст не кодируется UTF-8, даже если он хранится в базе данных Access в виде символов Юникода. Итак, для примера таблицы под названием "команды"

Team
-----------------------
Boston Bruins
Canadiens de Montréal
Федерация хоккея России

Код

<?php
header('Content-Type: text/html; charset=utf-8');
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Access character test</title>
</head>
<body>
<?php
$connStr = 
        'odbc:' .
        'Driver={Microsoft Access Driver (*.mdb)};' .
        'Dbq=C:\\Users\\Public\\__SO\\28311687.mdb;' .
        'Uid=Admin;';
$db = new PDO($connStr);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sql = "SELECT Team FROM Teams";
foreach ($db->query($sql) as $row) {
    $s = $row["Team"];
    echo $s . "<br/>\n";
}
?>
</body>
</html>

Отображает это в браузере

Boston Bruins
Canadiens de Montr�al
????????? ?????? ??????

Простые, но неполные исправления

Текст, возвращаемый Access, фактически соответствует символу Windows-1252 кодировка для символов в этом наборе символов, поэтому просто измените строку

$s = $row["Team"];

To

$s = utf8_encode($row["Team"]);

Позволит корректно отобразить вторую запись

Boston Bruins
Canadiens de Montréal
????????? ?????? ??????

Но функцияutf8_encode () преобразует из ISO-8859-1, Не Windows-1252 , поэтому некоторые символы (в частности, символ евро '€') исчезнут. Лучшим решением было бы использовать

$s = mb_convert_encoding($row["Team"], "UTF-8", "Windows-1252");

Но это все равно не решит проблему с третьей записью в нашем образец таблицы.

Полное Исправление

- полная поддержка UTF-8 нужно использовать ком с adodb соединение и recordset как так

<?php
header('Content-Type: text/html; charset=utf-8');
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Access character test</title>
</head>
<body>
<?php
$connStr = 
        'Driver={Microsoft Access Driver (*.mdb)};' .
        'Dbq=C:\\Users\\Public\\__SO\\28311687.mdb';
$con = new COM("ADODB.Connection", NULL, CP_UTF8);  // specify UTF-8 code page
$con->Open($connStr);

$rst = new COM("ADODB.Recordset");
$sql = "SELECT Team FROM Teams";
$rst->Open($sql, $con, 3, 3);  // adOpenStatic, adLockOptimistic
while (!$rst->EOF) {
    $s = $rst->Fields("Team");
    echo $s . "<br/>\n";
    $rst->MoveNext;
}
$rst->Close();
$con->Close();
?>
</body>
</html>