我需要能够在 Linux(特别是 Ubuntu 18.04)上读取从 Windows 系统复制的 .mdb(Microsoft Access© (JET) 文件)。我搜索了数十个网站,但找不到实现此目的的直接方法。大多数页面仅讨论如何在 Windows 系统上执行此操作,而 PHP 安装自然会附带对标准 Microsoft 数据库引擎的支持。特别是页面http://php.net/manual/en/pdo.drivers.php在描述中没有列出“Microsoft Access”或“JET”或“.mdb”或“.accdb”任何列出的驱动程序。
对于此应用程序,要求最终用户使用 mdbtools 之类的工具将 .mdb 文件转换为 MySQL/MariaDB/Postgres/SQLite/... 数据库会过于繁琐。用户界面必须能够识别包含客户现有数据的文件。然后将文件上传到服务器,读取其内容以初始化或更新服务器数据库,但转换并不简单,因为服务器 SQL 数据库的结构与 Access 数据库的结构不同,主要是因为设计此特定 Access 数据库的 DBA 认为永远不会需要多个用户同时访问数据库。此外,与大多数初学者一样,DBA 对几乎所有表都使用了服务器管理或“自动递增”主键。两个数据库中的确切数字键值不会相同。我没有在任何计算机上运行 Windows 的许可证,因此我无法测试仅在 Windows 上运行的实现。
一些网站建议使用 ODBC 作为解决方法,因此我安装了 php7.2-odbc 包,如下所示:
sudo apt install php7.2-odbc
...
Setting up php7.2-odbc (7.2.10-0ubuntu0.18.04.1) ...
Creating config file /etc/php/7.2/mods-available/odbc.ini with new version
Creating config file /etc/php/7.2/mods-available/pdo_odbc.ini with new version
Processing triggers for libapache2-mod-php7.2 (7.2.10-0ubuntu0.18.04.1)
请注意,要安装的软件包并不是特别明显,因为我找到的所有网页都指定要安装 php5-odbc 或 php7.0-odbc,具体取决于它们发布的年限,而软件包维护者可能很清楚,驱动程序包必须与已安装的 PHP 版本相匹配。不是对于只想安装“正确”软件包的最终用户来说,这一点显而易见。对于需要安装以扩展 PHP 的所有软件包而言,这都是一个问题。安装命令应该提供一种方法来选择所需的软件包,而不必强迫最终用户首先检查系统上运行的是哪个版本的 PHP。例如 apt-get install php*-odbc。
为了方便将来需要,我还安装了 SQLite 和 Postgres 驱动程序,同时还保留着所需的知识。
所以现在我的 Ubuntu 18.04 系统上对 PDO 的当前驱动程序支持总结如下:
php -i | grep PDO
PDO
PDO support => enabled
PDO drivers => mysql, odbc, pgsql, sqlite
PDO Driver for MySQL => enabled
PDO_ODBC
PDO Driver for ODBC (unixODBC) => enabled
PDO Driver for PostgreSQL => enabled
PDO Driver for SQLite 3.x => enabled
我重新启动了 Apache 服务器并且 phpinfo.php 显示所有驱动程序都已安装到位。
所以我从网页上抄了一些代码:
$db_username = ''; //username
$db_password = ''; //password
// path to database file
$database_path = "/home/jcobban/FamilyTree/Cobban.mdb";
// check file exist before we proceed
if (!file_exists($database_path)) {
die("Access database file not found !");
}
//create a new PDO object
$database = new PDO("odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ=$database_path; Uid=$db_username; Pwd=$db_password;");
$sql = "SELECT * FROM tableName";
$result = $database->query($sql);
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
print_r($row);
}
Fatal error: Uncaught PDOException: SQLSTATE[01000] SQLDriverConnect: 0 [unixODBC][Driver Manager]Can't open lib 'Microsoft Access Driver (*.mdb, *.accdb)' : file not found in /home/jcobban/public_html/testAccess.php:14 Stack trace: #0 /home/jcobban/public_html/testAccess.php(14): PDO->__construct('odbc:DRIVER={Mi...') #1 {main} thrown in /home/jcobban/public_html/testAccess.php on line 14
请注意,由于脚本并未在第 7 行终止,因此文件 Cobban.mdb 确实存在于该位置。
问题似乎是我没有安装正确的驱动程序,因为我找不到任何关于安装正确软件包名称的文档,或者每一个例如,我发现连接字符串应该是错误的,包括https://stackoverflow.com/questions/27066516/microsoft-access-with-php-and-pdo,https://stackoverflow.com/questions/23088127/setting-up-pdo-connection-class-for-microsoft-access-database等等。特别是,我找不到有关连接字符串的权威网站。网站 www.connectionstrings.com 仅从 ActiveX 数据对象 (ADO) 的角度讨论它们,而这些并不适用于 Linux。页面http://php.net/manual/en/ref.pdo-odbc.php仅包含如何将其与 MSSQL Server 一起使用的示例。
当我没有受到鼓励的时候将 PHP 连接到 Microsoft Access ODBC特别警告:“到处都有关于从 PHP 访问 Jet 数据库的指南,但它们都是转移注意力的花招 - 它们都假设您在安装了 MS Access 的 Windows 机器上运行 PHP,并使用 Windows 独有的 ODBC 驱动程序打开与 Access 捆绑在一起的 Jet(“access”)文件。这对 Linux 上的您毫无用处。”
因此,我继续在网上搜索,并确认了如上所述,全部PDO 的所有官方文档和所有志愿者提供的页面中的建议和示例仅适用于 Windows。我发现我需要安装以下内容:
sudo apt-get install odbc-mdbtools
sudo apt-get install unixodbc-dev
并更改连接字符串以指定“Driver = MDBTools;”。这主要解释在https://gist.github.com/amirkdv/9672857。所以我现在可以使用 PDO 读取 Access JET 文件。
我仍然找不到任何关于如何设置连接的文档,因此 .mdb 文件中使用的过时 UCS-2LE 编码被转换为 UTF-8,我在 MySQL/MariaDB 支持中使用了 UTF-8。这是由于缺少连接字符串文档,而这类信息应该在文档中指定。