Не удается подключиться к SQL Anywhere 12 с PHP и ODBC в Ubuntu

Я пытаюсь получить установку PHP 5.3.10 на Ubuntu 12.04 для подключения к удаленному серверу SQL Anywhere 12 (Sybase?) с использованием ODBC (unixODBC). Однако выполнение PHP останавливается на odbc_connect().

Код PHP:

$odbc = odbc_connect('DSN=TP189902;', 'username', 'password');

if ($odbc)
{
    echo 'Connected';
}
else
{
    echo 'Failed: '.odbc_error($odbc);
}

Таким образом, независимо от того, подключается он или нет, он должен выводить одно из эхо, но это не так. Если вместо этого я попытаюсь использовать библиотеку PHP PDO, я получу тот же результат.

Моя настройка unixODBC выглядит следующим образом. И это может быть моей ошибкой, потому что я никогда раньше не устанавливал ODBC в Linux и не очень хорошо с этим знаком.

odbcinst.ini

[SQL Anywhere 12]
Description = SQL Anywhere 12
Driver = /opt/sqlanywhere12/lib64/libdbodbc12.so
Setup  = /opt/sqlanywhere12/lib64/libdbodbc12.so

odbc.ini

[TP189902]
Description = TP189902
Uid = username
Pwd = password
Driver = SQL Anywhere 12
ServerName = 189902
CommLinks = tcpip(Host=1.2.3.4)
DatabaseName = DB189902

Я также пробовал множество альтернатив, таких как использование пути драйвера для значения драйвера, использование Host=1.2.3.4 вместо CommLinks и т. д.

Также команда isql -v TP189902 username password ничего не выводит, если я не даю ей фальшивый DSN, чтобы она выводила и выдавала ошибку.

Я также проверил, что libdbodbc12.so имеет ту же архитектуру, что и isql, и что он имеет все зависимости.

Кроме того, у меня очень похожая настройка на машине с Windows 7, на которой работает WAMP, которая прекрасно подключается (как с библиотекой ODBC, так и с библиотекой PDO). Я использовал те же данные DSN.

Редактировать: я также пытался пропустить DSN, но это дает тот же результат. Это также работает на коробке Windows.

$odbc = odbc_connect('Driver={SQL Anywhere 12};Server=189902;CommLinks=tcpip(Host=1.2.3.4);', 'username', 'password');

person Samutz    schedule 05.02.2014    source источник


Ответы (2)


В настоящее время я не использую PHP, но вот некоторые вещи, которые я заметил:

  1. Я бы полностью проигнорировал php, пока вы не заработаете isql.
  2. Я предполагаю, что это опечатка, что вы говорите, что ваш системный ini-файл «odbcinstr.ini» - это должно быть «odbcinst.ini».
  3. Как узнать, что вы просматриваете правильные файлы odbc ini — запустите odbcinst -j, чтобы проверить расположение, которое использует unixODBC.
  4. Я знаю, откуда берется этот раздел «[Источники данных ODBC]» (iodbc), но он совсем не нужен для unixODBC — просто удалите первые 2 строки вашего файла odbc.ini.
  5. в вашей строке isql, вероятно, отсутствуют имя пользователя и пароль - это должно быть «isql -v TP189902 username password». Я не могу понять, почему он вообще ничего не выводит.
person bohica    schedule 05.02.2014
comment
Спасибо за ответ. Разделение следующего из-за ограничения символов... 1. Каждый раз, когда я вношу изменения и пытаюсь снова, я пробую и php, и isql, потому что я не был уверен, что isql должен что-то выводить. 2. Да, в посте опечатка, но само имя файла написано правильно. - person Samutz; 05.02.2014
comment
3. Я тоже так делал. Единственное, что он указывает ~/.odbc.ini в качестве пользовательского файла DSN и /etc/odbc.ini в качестве системного DSN. Я использовал системный файл DSN, потому что я использовал его и в Windows. Я не уверен, имеет ли это значение. 4. Пробовал и с ним и без него. Я удалю это навсегда, хотя. 5. Я пробовал это несколько раз, но у меня сложилось впечатление, что наличие имени пользователя и пароля в конфигурации DSN сделает его не нужным для команды isql. Я стараюсь не вводить текст пароля в командах оболочки, но с этого момента я буду тестировать его. - person Samutz; 05.02.2014
comment
Введите пароль пользователя isql -v TP189902 и скажите мне, что произойдет. Вы должны получить либо ошибку, либо запрос на ввод SQL. Если вы не получите ни run strace -o x.log isql -v TP189902 имя пользователя и пароль, ни опубликуйте файл журнала где-нибудь, я могу его увидеть. - person bohica; 05.02.2014
comment
Он успешно открывает /opt/sqlanywhere12/lib64/libdbodbc12.so, но libdbodbc12_r.so из разных мест и не работает. Запустите ldd на /opt/sqlanywhere12/lib64/libdbodbc12.so, и он должен показать вам, от чего он зависит и чего не хватает. - person bohica; 05.02.2014
comment
Я сделал это с обоими файлами, и он не говорит, что чего-то не хватает. - person Samutz; 05.02.2014
comment
Позвольте мне увидеть вывод ldd на /opt/sqlanywhere12/lib64/libdbodbc12.so, а затем, если он действительно указывает, где находится libdbodbc12_r.so, запустите ls -la on_that_file, чтобы увидеть разрешения. - person bohica; 05.02.2014
comment
В нем нет libdbodbc12_r.so: pastebin.com/UZxRxiLL Но libdbodbc12_r.so находится в том же каталоге. - person Samutz; 05.02.2014
comment
Ваш strace ясно показал, что что-то (динамический компоновщик) постоянно пытается найти libdbodbc12_r.so и терпит неудачу. Обычно _r обозначает потокобезопасную версию библиотеки, если это помогает. Где-то должна быть ссылка/зависимость от этой библиотеки, которую вы просто еще не нашли. Попробуйте убедиться, что для переменной среды LD_LIBRARY_PATH установлено значение /opt/sqlanywhere12/lib64/, и экспортируйте ее перед запуском isql. - person bohica; 05.02.2014
comment
Хорошо, теперь это работает с набором переменных, но только для этого пользователя и из ~/.odbc.ini. Кажется, он полностью игнорирует файл /etc/odbc.ini. Мне нужно, чтобы он работал с любым пользователем, так как php запускается от другого пользователя. - person Samutz; 05.02.2014
comment
Также запуск odbcinst -j от имени пользователя теперь возвращает odbcinst: symbol lookup error: odbcinst: undefined symbol: odbcinst_system_file_name, но нормально работает как root/sudo. - person Samutz; 05.02.2014
comment
После дополнительных копаний и необходимости возиться с путями к библиотекам и переменными среды я близок к тому, чтобы заставить его работать. Простой PHP-скрипт, который я разместил выше, работает, но PHP-фреймворк, который я использую для проекта, не будет подключаться, поэтому мой вопрос больше не актуален. Спасибо за помощь. Это помогло мне приблизиться к полной работе. - person Samutz; 06.02.2014

В конечном итоге проблема заключалась в том, чтобы установить для LD_LIBRARY_PATH значение /opt/sqlanywhere12/lib64 для Apache.

Установка его в /etc/environment заставила isql -v TP189902 и php connect.php работать при вызове из любого пользователя оболочки, но не из Apache.

Чтобы Apache его увидел, мне пришлось отредактировать /etc/init.d/apache2 и изменить
ENV="env -i LANG=C PATH=/usr/local/bin:/usr/bin:/bin"
на
ENV="env -i LANG=C PATH=/usr/local/bin:/usr/bin:/bin LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/sqlanywhere12/lib64".
А затем перезапустить службу Apache. Различные другие методы, которые я нашел в Интернете, не сработали.

Одно предостережение заключается в том, что с установленным путем unixODBC по какой-то причине все равно не будет читать мой системный файл DSN. Поэтому, чтобы заставить Apache получить доступ к DSN, мне пришлось создать пользовательский файл DSN (.odbc.ini) в /var/www, так как это домашняя папка пользователя Apache (www-data).

person Samutz    schedule 06.02.2014