我在我的 CentOS7 服务器上正确设置了 unixODBC,以便与我的 Transoft ODBC 驱动程序一起使用,并且我可以使用以下命令成功连接和查询我试图访问的数据库:
isql -v 'DSN' 'user' 'pwd'
我采取了下一步并创建了一个 PHP 脚本来运行查询。
$connect = odbc_connect("integra.udd","user","pwd");
$query = "SELECT Company1,Product,Vendor,Description1 FROM ICMAST WHERE Company1=1 LIMIT 5";
$result = odbc_exec($connect, $query);
while(odbc_fetch_row($result)){
$product = odbc_result($result, 2);
$desc = odbc_result($result, 4);
print "\n$product $desc<br />";
}
如果我使用 root 在 root 中执行此操作PHP odbctest.php
,它有效,我得到了我应该得到的结果。此外,我可以使用 apache 用户su -s /bin/bash apache
并运行它,它就可以工作了。 (我验证Apache服务器使用apache
作为用户运行命令echo exec ('whoami');
在 PHP 脚本中)
但是,如果我转到浏览器并运行它,则会收到以下错误:
Warning: odbc_connect(): SQL error: [unixODBC][Driver Manager]Can't open lib '/usr/usql/sqlaccess/libtsodbc.so' : file not found, SQL state 01000 in SQLConnect in /var/www/html/2m/odbctest.php on line 10
使用 Apache 运行时找不到共享对象文件,但从任何用户运行时都可以找到。
首先,我假设存在权限问题,因此我更改了所有权libtsodbc.so
文件到apache:apache
。不用找了。
然后我检查了文件的权限,它设置为555
,因此应该可由用户执行。
然后我尝试在浏览器中运行 PHP 脚本来检查该文件是否存在于该路径中。这是我运行的脚本:
<?php
$filename = '/usr/usql/sqlaccess/libtsodbc.so';
if (file_exists($filename)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
?>
它返回该文件存在,因此即使 Apache 正在执行脚本,PHP 也可以看到它。
我放弃了它是 SELinux 或防火墙的想法,因为它甚至没有达到尝试连接的程度,当它尝试查找共享对象库文件时它会失败。所以问题一定是服务器内部的。
最后,我认为这可能与共享库路径有关,即使它正在查看错误中文件的实际路径但没有找到它。所以我尝试将以下行添加到我的 PHP 脚本中来设置LD_LIBRARY_PATH
:
putenv("LD_LIBRARY_PATH=/usr/usql/sqlaccess/");
没有改变,仍然给出文件未找到的错误。
我确信这很简单,因为我是一个完全的 Linux 初学者,但我不知道下一步该尝试什么。有任何想法吗?用户运行 PHP 脚本和 Apache 运行 PHP 脚本之间还有什么不同?
编辑添加
libtsodbc.so
, php
, and httpd
文件命令输出:
[root@intranetserver /]# file /usr/usql/sqlaccess/libtsodbc.so
/usr/usql/sqlaccess/libtsodbc.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
[root@intranetserver /]# file /usr/bin/php
/usr/bin/php: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=70ddc88b357d818240da4d4b3db50790c7913822, stripped
[root@intranetserver /]# file /usr/sbin/httpd
/usr/sbin/httpd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0890c878aa1d1a620d5c65d25a13d11cc2fdf96a, stripped