Невозможно получить символы UTF-8 с акцентом из Access через PDO_ODBC

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

Incorrect string value: '\xE9d'

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

ПРИМЕЧАНИЕ. Тот же самый оператор принимает, сохраняет и отображает штраф «é» в текстовом поле, которое используется для заголовка этой загрузки БД. Также, если я «сохраню как» страницу и снова открою ее, «é» будет отображаться правильно ….

Вот как я подключаюсь:

$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» в доступе, он сообщает мне 1033, что dbSortGeneral для «порядка сортировки по английскому, немецкому, французскому и португальскому языкам».

Что случилось? Это похоже на то, что PDO отправляет мне сопоставление моего браузера, а PHP не до конца понимает.

2

Решение

Эта проблема

При использовании собственных функций ODBC PHP (PDO_ODBC или более старых odbc_ функции) и драйвер 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"];

в

$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 нам нужно использовать COM с такими объектами ADODB Connection и 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>
10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]