Резюме
Я пытаюсь выполнить запрос к базе данных Vertica, используя PHP 7.0.9 и PDO через соединение ODBC, но специальные символы, такие как акцентированные буквы и символ EURO, не отображаются должным образом на сгенерированной странице HTML.
Согласно Vertica Docs:
Ожидается, что все входные данные, полученные сервером базы данных, будут в формате UTF-8, а все данные Vertica — в формате UTF-8.
Настройка среды
ОС CentOS Linux версии 7.2.1511 с ядром 3.10.0-327.28.3.el7.x86_64
Установленные пакеты PHP 7.0.9:
php70w-cli-7.0.9-1.w7.x86_64
php70w-7.0.9-1.w7.x86_64
php70w-pear-1.10.1-1.w7.noarch
php70w-odbc-7.0.9-1.w7.x86_64
php70w-mbstring-7.0.9-1.w7.x86_64
php70w-common-7.0.9-1.w7.x86_64
php70w-process-7.0.9-1.w7.x86_64
php70w-xml-7.0.9-1.w7.x86_64
php70w-pecl-xdebug-2.4.0-1.w7.x86_64
php70w-pdo-7.0.9-1.w7.x86_64
Дополнительные пакеты:
unixODBC-2.3.1-11.el7.x86_64
vertica-client-7.2.3-0.x86_64
Соответствующие файлы конфигурации:
/etc/vertica.ini
[Driver]
DriverManagerEncoding=UTF-16
ODBCInstLib=/usr/lib64/libodbcinst.so
ErrorMessagesPath=/opt/vertica
LogLevel=4
LogPath=/tmp
/etc/odbcinst.ini
[HPVertica]
Description = Vertica ODBC Driver
Driver = /opt/vertica/lib64/libverticaodbc.so
[ODBC]
Threading = 1
файла /etc/odbc.ini
[ODBC Data Sources]
Test_Vertica = "Test Vertica"
[Test_Vertica]
Description = Test Vertica
Driver = HPVertica
Database = VMart
Servername = <redacted>
UID = <redacted>
PWD = <redacted>
Port = 5433
Прецедент
Если я создаю таблицу со специальными символами и запрашиваю ее, результаты правильно отображаются в терминале (переменная среды $LANG
установлен в en_US.UTF-8
):
# /opt/vertica/bin/vsql -h <redacted> -d VMart -U dbadmin
VMart=> create table stackoverflow(str varchar(100));
VMart=> insert into stackoverflow(str) values ('àèìòù €uro');
VMart=> commit;
# /opt/vertica/bin/vsql -h <redacted> -d VMart -U dbadmin -c 'select * from stackoverflow'
str
------------
àèìòù €uro
(1 row)
# echo 'select * from stackoverflow' | isql Test_Vertica
SQL> select * from stackoverflow
+-----------------------------------------------------------------------------------------------------+
| str |
+-----------------------------------------------------------------------------------------------------+
| àèìòù €uro |
+-----------------------------------------------------------------------------------------------------+
SQLRowCount returns 1
1 rows fetched
Тем не менее, этот простой PHP-скрипт отправит мусор пользовательскому агенту:
<?php
$dbconn = new PDO('odbc:Test_Vertica');
$sql = 'select * from stackoverflow';
$statement = $dbconn->prepare($sql);
$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
header('Content-Type: text/html; charset=utf-8');
var_dump($results);
Выход в терминал:
# php /var/www/html/stackoverflow.php
/var/www/html/stackoverflow.php:8:
array(1) {
[0] =>
array(1) {
'str' =>
string(17) "àèìòù €uro"}
}
Вывод в браузере (также пробовал в последних версиях Chrome и IE):
# elinks -dump http://localhost/stackoverflow.php
/var/www/html/stackoverflow.php:10:
array (size=1)
0 =>
array (size=1)
'str' => string '..... .uro' (length=10)
Похоже, что вместо специальных символов пользовательский агент отправляет код SUB ASCII (шестнадцатеричный 1A). Некоторые браузеры отображают его как точку, другие как пробел.
Есть идеи? Благодарю.
Задача ещё не решена.
Других решений пока нет …