Help us understand the problem. What is going on with this article?

PHPからAccessDBに接続する

今どき・・・な感じですが、ある案件でPHPからAccessDBに接続して情報を取得する必要があったのでそのメモです。
ネットで調べてもあんまり情報がなかったので残します。
単にPHP-->Accessっていうパターンが少ないだけだとは思うのですが。

環境

PHP7.2 32bit
Apache 2.4 32bit
Access 2010(2017でもOK) 32bit

大事なところ

あまりないかもしれませんが、Accessが32bitならばPHP、Apacheも32bitで揃える。
64bitであれば64bitで揃えないと正しく動きません。(少なくとも私の環境では動かなかった)

接続

PDOで接続します。

db.php
define('ACCESS_DB_DRIVER',   '{Microsoft Access Driver (*.mdb, *.accdb)}');
define('ACCESS_DBQ',         'C:\\test\\test_be.accdb');
define('ACCESS_DB_USER',     '');
define('ACCESS_DB_PASSWORD', '');

$objPdo = new PDO("odbc:Driver=" . ACCESS_DB_DRIVER . ";Dbq=" . ACCESS_DBQ . "; Uid=" . ACCESS_DB_USER . "; Pwd=" . ACCESS_DB_PASSWORD . " ;");

Driver

データソースのドライバーの部分を指定します。
20190410_datasource.png

DBQ

AccessDB(***.accdb)のフルパスを指定します。
ここで指定するのはAccessで「データベースの分割」を行ったデータベースのみのファイルになります。

DB_USER、DB_PASSWORD

今回は使用していません。

クエリ実行

test.php
<?php

ini_set('INTERNAL_ENCODING', 'UTF-8');

define('ACCESS_DB_DRIVER',   '{Microsoft Access Driver (*.mdb, *.accdb)}');
define('ACCESS_DBQ',         'C:\\test\\test_be.accdb');
define('ACCESS_DB_USER',     '');
define('ACCESS_DB_PASSWORD', '');

$objPdo = new PDO("odbc:Driver=" . ACCESS_DB_DRIVER . ";Dbq=" . ACCESS_DBQ . "; Uid=" . ACCESS_DB_USER . "; Pwd=" . ACCESS_DB_PASSWORD . " ;");

$sql = "SELECT test_column FROM tbl_test WHERE column = 10;";
$sql = convertSJIS($sql); // 文字コード変換。AccessはSJIS-winなので変換する必要あり
$stmt = $objPdo->prepare($sql);
$result = $stmt->execute();
if ($result !== false) {
    $arrData = $stmt->fetchAll(PDO::FETCH_ASSOC);
    foreach ($arrData as $arrDetail) {
        $strValue = convertUTF8($arrDetail['test_column']); // SJIS-winからUTF-8に変換する
    }
}

/**
 * 文字コードを変換する
 * UTF-8 --> SJIS-win 
 */
function convertSJIS($strTmp) {
    return mb_convert_encoding($strTmp, "SJIS-win", "UTF-8");
}

/**
 * 文字コードを変換する
 * SJIS-win --> UTF-8
 */
function convertUTF8($strTmp) {
    return mb_convert_encoding($strTmp, "UTF-8", "SJIS-win");
}

ポイントとしてはAccessの文字コードがSJIS-winなので、クエリ発行時はUTF-8 --> SJIS-winへ、取得したデータはSJIS-win-->UTF-8に変換する必要があります。
取得するカラム名が日本語の場合はそれも変換する必要があるので、fetchAllしたあとにループですべて変換する必要がありますね。

おまけ

このコードをテストしていたときに気づいたのですが、mb_convert_encoding関数の第1引数に連想配列を渡すと、中身をすべて変換してくれるんですね。
PHP5.4ではエラーになったのでPHP7あたりからOKになったのかな?
公式にも配列OKとはなっていないので、正式なコードではないんだとは思います。

test.php
$arrData = $stmt->fetchAll(PDO::FETCH_ASSOC);
$arrData = convertUTF8($arrData);// これで配列の中身全部変換できる
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away