CentOS 7 に PHP 7.4 と phpMyAdmin をインストール

導入
====
CentOS 7 の公式リポジトリでは、非常に古いバージョンである PHP 5.4 が提供されています。PHP 5.4 〜 7.1 はアクティブサポートの終了に加え、セキュリティサポートまで終了したバージョンです。[^php]

RHEL/CentOS 6 では、バックポートなどによって PHP 5.3 のセキュリティが保たれているような状況ではあります。しかしながら後方互換性を保つ開発は困難であるため、古い PHP で利用できるライブラリは限られてきます。また、そのような開発はコストを増加させ、Web の発展を遅らせる要因ともなり得ます。 **(もっとも普及しているPHPテストフレームワークのPHPUnitが、すでにPHP 7.1以下のサポートを完全に終了しています [^phpunit])**

そこで remi リポジトリを追加し、そちらから最新バージョンをインストールします。

[^php]: [PHP: Supported Versions](https://www.php.net/supported-versions.php)
[^phpunit]: [Supported Versions of PHPUnit – The PHP Testing Framework](https://phpunit.de/supported-versions.html)

PHP のインストール
==================
remi リポジトリの公式サイトには長い指紋鍵が記載されていないため、[English : Repository Configuration — Remi’s RPM repository — Blog] の「4. Remi's signature Installation (GPG Key)」に記載されているURL (「This GPG key」のリンク先) から、あらかじめ GPG 公開鍵を取り込んでおきます。remi-release の依存関係で epel-release がインストールされます。

```sh
# remiリポジトリの公開鍵を取り込む
sudo rpm --import https://rpms.remirepo.net/RPM-GPG-KEY-remi

# yum-config-manager コマンドのインストールと remiリポジトリの追加
sudo yum install yum-utils https://rpms.remirepo.net/enterprise/remi-release-7.rpm

# remi-php74 リポジトリを有効化
sudo yum-config-manager --enable remi-php74

# PHP と拡張モジュールなどをインストール
sudo yum install php php-mbstring php-intl
```

* php-mbstring ([マルチバイト文字列拡張モジュール]) は、文字列 (UTF-8) のセキュリティを確保するのに必要です。ComposerやphpMyAdminをyumでインストールする場合、依存関係で自動的にインストールされます。
* php-intl ([Intl拡張モジュール]) は、文字列 (Unicode) に関する処理などに必要です。Composerなどをyumでインストールする場合、依存関係で自動的にインストールされます。
* yum リポジトリでは PECL 拡張モジュールも提供されているので、`pecl` コマンドでコンパイルを行う必要が無い場合もあります。
* 必要な拡張モジュールがあれば、合わせてインストールしておきます。

次の記事などを参考に PHP の設定を行います。

* [ソケット通信を利用している場合 | Apache に関する SELinux の設定 — Qiita](https://qiita.com/100/items/f7f43994568836b4a453#追記ソケット通信を利用している場合 "PHPなどのプログラムからWhois検索をしたりするために、ソケット通信が必要になりますが、SELinuxは既定でこれを許可しません。")
* [PHP 7.1 設定ファイルの記述例 (Apache 2.4) — Qiita](https://qiita.com/100/items/635bcb3b4291dc428eda)

[English : Repository Configuration — Remi’s RPM repository — Blog]: https://blog.remirepo.net/pages/Config-en "Download addresses, howto on RPM installation and YUM/DNF repository configuration for this site."
[マルチバイト文字列拡張モジュール]: https://www.php.net/manual/book.mbstring.php "mbstring はマルチバイト対応の文字列関数を提供し、 PHP でマルチバイトエンコーディングを処理することを容易にします。"
[Intl拡張モジュール]: https://www.php.net/manual/book.intl.php "国際化用拡張モジュール (Intl と略します) は ICU ライブラリのラッパーです。 PHP プログラマが、UCA 準拠の照合順序 (collation) や日付/時刻/数値/通貨のフォーマットを扱えるようにします。"

DBMS ドライバのインストール
===========================

```sh
# PDO_MYSQLのインストール
sudo yum install php-mysqlnd
```

`php-mysqlnd` は、利用するデータベース管理システムに合わせて読み替えてください。以下は関係データベース管理システムのドライバとパッケージ名の対応表です。

| RDBMS                      | 拡張モジュール | RPM パッケージ  |
|----------------------------|----------------|-----------------|
| Adaptive Server Enterprise | [PDO_DBLIB]    | `php-mssql`     |
| DB2                        | [PDO_ODBC]     | `php-odbc`      |
| Firebird                   | [PDO_FIREBIRD] | `php-interbase` |
| InterBase                  | [PDO_FIREBIRD] | `php-interbase` |
| MariaDB                    | [PDO_MYSQL]    | `php-mysqlnd`   |
| Microsoft SQL Server       | [PDO_DBLIB]    | `php-mssql`     |
| MySQL                      | [PDO_MYSQL]    | `php-mysqlnd`   |
| Oracle Database            | [PDO_OCI]      | `pdo-oci8`      |
| PostgreSQL                 | [PDO_PGSQL]    | `php-pgsql`     |
| SQLite                     | [PDO_SQLITE]   | `php-pdo`       |

上の表にないデータベースに関しては、[development/languagesパッケージ一覧] から拡張モジュールの RPM パッケージを見つけることができるかもしれません。 

[PDO_DBLIB]: https://www.php.net/manual/ref.pdo-dblib.php "PDO_DBLIB は PHP Data Objects (PDO) インターフェイスを実装したドライバで、 PHP から Microsoft SQL Server および Sybase データベースに対して FreeTDS ライブラリを使用したアクセスが可能となります。"
[PDO_ODBC]: https://www.php.net/manual/ref.pdo-odbc.php "PDO_ODBC は PHP Data Objects (PDO) インターフェイスを実装したドライバで、 PHP から ODBC ドライバあるいは IBM DB2 Call Level Interface (DB2 CLI) ライブラリを使用した データベースへのアクセスが可能となります。"
[PDO_FIREBIRD]: https://www.php.net/manual/ref.pdo-firebird.php "PDO_FIREBIRD は、PHP から Firebird データベースへのアクセスを可能にするための PHP Data Objects (PDO) インターフェイス を実装したドライバです。"
[PDO_MYSQL]: https://www.php.net/manual/ref.pdo-mysql.php "PDO_MYSQL は、PHP から MySQL 3.x、4.x および 5.x データベースへのアクセスを可能にするための PHP Data Objects (PDO) インターフェイス を実装したドライバです。"
[PDO_OCI]: https://www.php.net/manual/ref.pdo-oci.php "PDO_OCI は、OCI ライブラリを通じて PHP から Oracle データベースへのアクセスを可能にするための PHP Data Objects (PDO) インターフェイス を実装したドライバです。"
[PDO_PGSQL]: https://www.php.net/manual/ref.pdo-pgsql.php "PDO_PGSQL は、PHP から PostgreSQL データベースへのアクセスを可能にするための PHP Data Objects (PDO) インターフェイス を実装したドライバです。"
[PDO_SQLITE]: https://www.php.net/manual/ref.pdo-sqlite.php "PDO_SQLITE は、PHP から SQLite 2 や SQLite 3 データベースへのアクセスを可能にするための PHP Data Objects (PDO) インターフェイス を実装したドライバです。"
[development/languagesパッケージ一覧]: https://rpms.remirepo.net/enterprise/7/php74/x86_64/repoview/development.languages.group.html

phpMyAdmin
==========
この節の解説は、前節[PHP のインストール]の手順に従って remi-php74 リポジトリが有効化されていることを前提としていますので、ご注意ください。

[PHP のインストール]: #php-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

インストールするパッケージの制限
--------------------------------
phpMyAdmin 最新安定版のパッケージは `remi` リポジトリにありますが、remi リポジトリを有効化すると、PHP のバージョンに関係ない標準リポジトリなどのパッケージ (remi リポジトリからインストールする必要のないパッケージ) が上書きされます。そこで remi リポジトリにおいて、`phpMyAdmin` と依存パッケージのみ有効にします。

リポジトリ定義ファイル (\*.repo) でシンタックスハイライトを有効化する場合は、[*.repo のシンタックスハイライト]を参照してください。

```ini:/etc/yum.repos.d/remi.repo
[remi]
name=Remi's RPM repository for Enterprise Linux 7 - $basearch
#baseurl=http://rpms.remirepo.net/enterprise/7/remi/$basearch/
mirrorlist=http://rpms.remirepo.net/enterprise/7/remi/mirror
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi
includepkgs=phpMyAdmin php-phpmyadmin-* php-symfony-* php-symfony4-* php-tcpdf php-tcpdf-dejavu-sans-fonts php-pragmarx-google2fa-qrcode php-pragmarx-google2fa5 php-williamdes-mariadb-mysql-kbs php-twig2 php-psr-event-dispatcher php-nikic-fast-route
## ↑この行を追加 ##

                        ##############
                        ## 以下省略 ##
                        ##############
```

[*.repo のシンタックスハイライト]: https://qiita.com/100/items/5a07ab0abcabd1296ef8#repo-%E3%81%AE%E3%82%B7%E3%83%B3%E3%82%BF%E3%83%83%E3%82%AF%E3%82%B9%E3%83%8F%E3%82%A4%E3%83%A9%E3%82%A4%E3%83%88

インストール
------------
EPEL7のGPG公開鍵を取り込んでも良いか訊ねられた場合、Fingerprintが https://getfedora.org/security/ の指紋と大文字小文字無視で一致するか確認します。

```sh
# remi リポジトリを有効化
sudo yum-config-manager --enable remi

# インストール
sudo yum install phpMyAdmin
```

依存性関連でインストールされる php-pear パッケージは、ディレクトリ `/var/www/html` が読み取り専用の場合インストールに失敗するのでご注意ください。

phpMyAdmin 用データベースの作成
-------------------------------

```sql:/usr/share/phpMyAdmin/sql/create_tables.sql
                        --------------
                        -- 以上省略 --
                        --------------

-- --------------------------------------------------------

--
-- Privileges
--
-- (activate this statement if necessary)
GRANT SELECT, INSERT, DELETE, UPDATE, ALTER ON `phpmyadmin`.* TO
  'pma'@localhost;
-- ↑この2行のコメントアウトを外す --

-- --------------------------------------------------------

                        --------------
                        -- 以下省略 --
                        --------------
```

`mysql --user=root --password` を実行し、MariaDB の root ユーザーでログインします。[^記号]

```sql
-- phpMyAdmin用のデータベース・ユーザーを作成
source /usr/share/phpMyAdmin/sql/create_tables.sql

-- パスワードの設定
SET PASSWORD FOR pma@localhost = PASSWORD('⦅pmaのパスワード⦆');

-- 権限テーブルの再読み込み
FLUSH PRIVILEGES;

-- ログアウト
exit
```

[^記号]: いざログインしようとしたときに認証失敗しないよう、[記号や暗号化方式の互換性](https://qiita.com/100/items/dd13912f1cf5ea14d42a#-%E8%A8%98%E5%8F%B7%E3%82%84%E6%9A%97%E5%8F%B7%E5%8C%96%E6%96%B9%E5%BC%8F%E3%81%AE%E4%BA%92%E6%8F%9B%E6%80%A7) に目を通しておいてください。

設定
----

```php:/etc/phpMyAdmin/config.inc.php
                        //////////////
                        // 以上省略 //
                        //////////////

/**
 * phpMyAdmin configuration storage settings.
 */

/* User used to manipulate with storage */
// $cfg['Servers'][$i]['controlhost'] = '';
// $cfg['Servers'][$i]['controlport'] = '';
$cfg['Servers'][$i]['controluser'] = 'pma';                 // コメントアウトを外す //
$cfg['Servers'][$i]['controlpass'] = '⦅pmaのパスワード⦆';   // コメントアウトを外し、「pmapass」を修正 //

/* Storage database and tables */
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
$cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
$cfg['Servers'][$i]['relation'] = 'pma__relation';
$cfg['Servers'][$i]['table_info'] = 'pma__table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma__column_info';
$cfg['Servers'][$i]['history'] = 'pma__history';
$cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
$cfg['Servers'][$i]['tracking'] = 'pma__tracking';
$cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
$cfg['Servers'][$i]['recent'] = 'pma__recent';
$cfg['Servers'][$i]['favorite'] = 'pma__favorite';
$cfg['Servers'][$i]['users'] = 'pma__users';
$cfg['Servers'][$i]['usergroups'] = 'pma__usergroups';
$cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding';
$cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
$cfg['Servers'][$i]['central_columns'] = 'pma__central_columns';
$cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings';
$cfg['Servers'][$i]['export_templates'] = 'pma__export_templates';
        // ↑ここまでコメントアウトを外す //

/**
 * End of servers configuration
 */

                        //////////////
                        //   中略   //
                        //////////////

/*
 * You can find more configuration options in the documentation
 * in the doc/ folder or at <http://docs.phpmyadmin.net/>.
 */

// root アクセスの禁止
$cfg['Servers'][$i]['AllowRoot'] = false;
// ↑ファイル末尾にこの行を追加 //
```

Apache の設定
-------------
### URL

```apacheconf:/etc/httpd/conf.d/phpMyAdmin.conf
# phpMyAdmin - Web based MySQL browser written in php
# 
# Allows only localhost by default
#
# But allowing phpMyAdmin to anyone other than localhost should be considered
# dangerous unless properly secured by SSL

#Alias /phpMyAdmin /usr/share/phpMyAdmin
#Alias /phpmyadmin /usr/share/phpMyAdmin
## ↑コメントアウトする ##

<Directory /usr/share/phpMyAdmin/>

                        ##############
                        ## 以下省略 ##
                        ##############
```

Apache で扱うドメイン名が一つの場合は上でコメントアウトした箇所の下に、複数の場合は phpMyAdmin にアクセスするドメイン名の <VirtualHost> セクションに `Alias /⦅任意の英数字⦆ /usr/share/phpMyAdmin` を記述します。[^パス]

[^パス]: URL のパス部分にそのまま使用可能なASCII記号 `!$&'()*+,-.:;=@[]^_|~` を混ぜたパスにしたところ、phpMyAdmin へログインしてもログイン前のページしか表示されなかった。

### アクセス制限
デフォルトではローカルのブラウザからしかアクセスできません。以下のように [Requireディレクティブ] を変更すると、どこからでもアクセスできるようになります。

アクセス元のIPアドレスが決まっている場合は、`Require ip 2001:db8::a00:20ff:fea7:ccea` のようにアクセスを制限した方が良いでしょう。
Requireディレクティブの引数について、詳しくは [mod_authz_hostのドキュメント(英語)] をご覧ください。

TLS による暗号化 (HTTPS) などを用いずに外部から phpMyAdmin アクセスすると、データベースのユーザー名やパスワードがネットワーク上を平文で流れることになり大変危険です。

```apacheconf:/etc/httpd/conf.d/phpMyAdmin.conf
# phpMyAdmin - Web based MySQL browser written in php
# 
# Allows only localhost by default
#
# But allowing phpMyAdmin to anyone other than localhost should be considered
# dangerous unless properly secured by SSL

Alias /phpMyAdmin /usr/share/phpMyAdmin
Alias /phpmyadmin /usr/share/phpMyAdmin

<Directory /usr/share/phpMyAdmin/>
   AddDefaultCharset UTF-8

   <IfModule mod_authz_core.c>
     # Apache 2.4
     Require all granted
     ## ↑ Require ディレクティブの引数を「local」から「all granted」に
   </IfModule>
   <IfModule !mod_authz_core.c>
     # Apache 2.2
     Order Deny,Allow
     Deny from All
     Allow from 127.0.0.1
     Allow from ::1
   </IfModule>
</Directory>

                        ##############
                        ## 以下省略 ##
                        ##############
```

[Requireディレクティブ]: https://httpd.apache.org/docs/current/mod/mod_authz_core.html#require "This directive tests whether an authenticated user is authorized according to a particular authorization provider and the specified restrictions."
[mod_authz_hostのドキュメント(英語)]: https://httpd.apache.org/docs/current/mod/mod_authz_host.html "These authorization providers affect which hosts can access an area of the server. Access can be controlled by hostname, IP Address, or IP Address range."