Win64 AMP スタックを一から構築する

# 目標 #

64-bit Windows 10 で、XAMPP や bitnami WAMP などのパッケージに頼らずに、開発環境としての AMP スタックを一から構築する。スタックの構成は、以下のとおり。

- Apache 2.4
- PHP 7.4
- MySQL の代りに MariaDB
- および、これらの付属ユーティリティ

PHP 8.0 を入れたいのだが、2021年5月現在、ImageMagick がまだ対応していないので、一つ古い PHP 7.4 を使う。

# ルート・ディレクトリ #

C: ドライブのルートに `kamp` というディレクトリを作成。`k` は `kihara` の `k`。この `C:\kamp` の下にサブ・ディレクトリを作って Apache, PHP, MariaDB, MySQLを入れる予定。

それらを直接 `C:\` 直下に入れても構わない。その方が作業は楽だろう。

# Visula C++ ランタイム #

ここで使用する Apache 2.4 や PHP 7.4 などは、**Visual C++** のランタイムに依存しているので、Microsoft のサイト "[最新のサポートされる Visual C++ のダウンロード](https://support.microsoft.com/ja-jp/help/2977003/the-latest-supported-visual-c-downloads)" から `vc_redist.x64.exe` をダウンロードしてインストールする。これは、VC++ 2015(VC14), VC++ 2017(VC15), および VC++ 2019(VS16) に共通のランタイム・ライブラリである。64-bit 版を使う。

以下、Apache と PHP および PHP エクステンションのバイナリを入手するときは、**VC15 または VS16** でコンパイルされた **x64** 用のものを選んでダウンロードする。

# Apache 2.4 #

## インストール ##

Apache 2.4.47 Win64 (httpd-2.4.47-win64-VS16.zip) を [Apache Lounge](https://www.apachelounge.com/download/) からダウンロードし、`C:\kamp\Apache24` に展開する。

`C:\kamp\Apache24\conf\httpd.conf` の中の、`c:/Apache24` をすべて `C:/kamp/Apache24` に変更する。

## サービスに登録 ##

アパッチをサービスとして登録する。すなわち、コマンド・プロンプトを管理者権限で起動して、以下のコマンドを実行する。

```bat
C:\kamp\Apache24\bin\httpd -k install
```

## ApacheMonitor ##

ApacheMonitor をスタート・アップに登録する。

`C:\kamp\Apache24\bin\ApacheMonitor.exe` のショートカットを`C:\Users\xxxx\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup` に入れれば良い。

以上で、とりあえず、Apache が動くことを確認する。`http://localhost/` にブラウザでアクセスして、"It Works!" と出ればオーケー。

## index.html ##

"動くぜ!" では味気ないので、`C:\kamp\Apache24\htdocs\index.html` を適当にいじる。後で加えたものを含めると、最終的には、こんな感じになった。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Apache 2.4</title>
</head>
<body>
<h1>Apache 2.4</h1>
<p>Running ... </p>
<h2>ユーティリティ</h2>
<ul>
  <li><a href="phpinfo.php">phpinfo</a></li>
  <li><a href="opcache.php">OPCache</a></li>
  <li><a href="apc.php">APCu</a></li>
  <li><a href="phpmyadmin/index.php">phpMyAdmin</a></li>
</ul>
</body>
</html>
```

# PHP 7.4 #

## インストール ##

[windows.php.net] (http://windows.php.net/download/) から、"VC15 x64 Thread Safe (2021-May-04 18:12:24)" の zip ファイル (php-7.4.19-Win32-vc15-x64.zip) をダウンロードして、`C:\kamp\php` 以下に展開する。

システム環境変数の `PATH` に `C:\kamp\php` を追加する。そうしないと、いくつかのエクステンションが、依存する DLL を読み込むことが出来なくてスカタンする (例えば、php_curl.dll が libeay32.dll と ssleay32.dll を読み込めない) 。


## Apache との連携 ##

`C:\kamp\Apache24\conf\extra\httpd-php.conf` によって PHP 用設定を追加する。

```apache:httpd-php.conf
LoadModule php7_module c:\kamp\php\php7apache2_4.dll
AddHandler application/x-httpd-php .php
PHPIniDir "C:/kamp/php"
<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>
```

メインの `C:\kamp\Apache24\conf\httpd.conf` で上記をインクルードする。

```apache
# for PHP
Include conf/extra/httpd-php.conf
```

## phpinfo ##

PHP 情報確認用に、`phpinfo.php` というファイルを `C:\kamp\Apache24\htdocs` に作成する。中身は、至極簡単。

```php:phpinfo.php
<?php
phpinfo(
    INFO_GENERAL 
    // | INFO_CREDITS
    | INFO_CONFIGURATION
    | INFO_MODULES
    | INFO_ENVIRONMENT
    | INFO_VARIABLES
    // | INFO_LICENSE
);
```

これを `index.html` からリンクする。

ApacheMonitor で apache を再起動してから `http://localhost/` にアクセスして、PHP との連携が有効になっていることを確認する。

## php.ini ##

`C:\kamp\php\php.ini-development` をコピーして `C:\kamp\php\php.ini` を作成し、編集する。

タイムゾーンを設定する。

```ini:php.ini
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = 'Asia/Tokyo'
```

エクステンションを有効にする。まず、`extension_dir` を適切に設定する必要がある。

```ini:php.ini
; On windows:
extension_dir = "c:/kamp/php/ext"
```

そして、適当に、必要と思われるエクステンションを有効にする。

```ini:php.ini
extension=bz2
extension=curl
extension=fileinfo
extension=gd
extension=gettext
;extension=gmp
extension=intl
...
extension=mbstring
extension=exif
extension=mysqli
...
extension=pdo_mysql
;extension=pdo_oci
```

後は、必要になったときに追加すればよいだろう。

なお、かつては `extension=php_<ext>.dll` と書いていたが、今は `extension=<ext>` と書く。

## OPCache ##

Zend OPCache を有効にする。

```ini:php.ini
zend_extension=opcache
...
[opcache]
; Determines if Zend OPCache is enabled
opcache.enable=1
```

`php_opcache.dll` は、既に、`ext` ディレクトリに入っている。`extension` ではなく、`zend_extension` である。

https://github.com/amnuts/opcache-gui から、OPCache の Web UI を取得する。必要なのは、`index.php` だけ。これを `opcache.php` などに名前を変えて、`C:\kamp\Apache24\htdocs` に置いて、`index.html` からリンクする。


## APCu ##

APCu のエクステンションは入っていないので、[PECL website - APCu](https://pecl.php.net/package/APCu) または [windows.php.net - /downloads/pecl/releases/apcu](https://windows.php.net/downloads/pecl/releases/apcu) からパッケージをダウンロードする必要がある。

最新である 5.1.20 の "PHP 7.4 Thread Safe (TS) X64"版 (php_apcu-5.1.20-7.4-ts-vc15-x64.zip) をダウンロードし、書庫の中に入っている `php_apcu.dll` を `C:\kamp\php\ext` の中に入れる。そして、`php.ini` に以下を追加する。

```ini:php.ini
[APCu]
extension = apcu
apc.enabled = 1
apc.shm_size = 64M
```

また、[PECL website - APCu](https://pecl.php.net/package/APCu) から、ソースファイル (apcu-5.1.20.tgz) をダウンロードする。この中に Web UI `apc.php` があるので、これを `C:\kamp\Apache24\htdocs` に置いて、`index.html` からリンクする。`apc.php` の 33 行目以下をちょっと修正して、ログイン出来るようにしておく。

```php:apc.php
defaults('USE_AUTHENTICATION',0);  // 1 を 0 に変更
```
これで無条件にログイン出来るようになる。

それではいかにも気持ちが悪いと思った場合は、ローカルの開発環境でそんなことをする必要はないと思うが、パスワードを設定すれば良い。

```php:apc.php
defaults('USE_AUTHENTICATION',1);
...
defaults('ADMIN_USERNAME','apc');
defaults('ADMIN_PASSWORD','xxxxxxxx');
```

パスワードを `password` 以外の文字列に変えなければならないのである。

### APCu_bc ###

使用している PHP アプリが APCu ではなく古い APC の API に依存している場合、APCu だけでは動かない。後方互換のためのパッケージ APCu_bc が必要である。

APCu_bc の Windows 用の最新版は [PECL website - APCu_bc](https://pecl.php.net/package/apcu_bc) にある。または、困ったときの
 [windows.php.net](http://windows.php.net/)、その奥まったところ、[windows.php.net - /downloads/pecl/releases/apcu_bc/1.0.5/](http://windows.php.net/downloads/pecl/releases/apcu_bc/1.0.5/) 以下に置いてある "php_apcu_bc-1.0.5-7.4-ts-vc15-x64.zip" をダウンロードする。この中に入っている `php_apc.dll` を `C:\kamp\php\ext` に入れて使う。

```ini:php.ini
[APCu_bc]
extension = apc
```

## Xdebug ##

Xdebug も付いてこないので、別途、[xdebug.org](http://xdebug.org/) からダウンロードする。現時点での最新バージョンは、3.0.4 である。

"PHP 7.4 VC15 TS (64 bit)" (php_xdebug-3.0.4-7.4-vc15-x86_64.dll) を取ってくる。長ったらしい名前を `php_xdebug.dll` に変更して `ext` ディレクトリに置く。

`php.ini` に、下記を追記。これも `zend_extension`。

```ini:php.ini
[XDebug]
zend_extension=xdebug
;xdebug.remote_enable = 1
xdebug.mode=debug
```
`xdebug.remote_enable` は廃止されたので `xdebug.mode` を使え、とのこと。


## ImageMagick ##

[ImageMagick のサイト](http://www.imagemagick.org/script/index.php)で、64-bit 版 Windows 用の最新版をダウンロードしてインストールしても良いのだろうが、PHP から ImageMagick の API を呼び出して使う限りでは、そこまでする必要は無い。

[windows.php.net - /downloads/pecl/releases/imgagick/](https://windows.php.net/downloads/pecl/releases/imagick/) または [PECL website - imagick](https://pecl.php.net/package/imagick) で、最新のライブラリ (現時点では、3.4.4) をダウンロードする。"php_imagick-3.4.4-7.4-ts-vc15-x64.zip" を選ぶこと。

中に沢山ファイルが入っているが、必要なのは `.dll` だけで（と言ってもかなり沢山あるが）、これを `C:\kamp\php\ext` ディレクトリに入れて、`C:\kamp\php\ext` にパスを通せば良い。（パスを通さなくても Apache から利用する限りでは問題が無いようなのだが、何故だか、コマンドラインで php を使うときに `imagick` をロード出来ないと文句を言われる。）

`php.ini` に、下記を追記。

```ini:php.ini
[ImageMagick]
extension=imagick
```
# MariaDB #

[MariaDB のサイト](http://mariadb.org/) から、mariadb-10.5.10-winx64.msi をダウンロードして、`C:\kamp\mariadb` にインストールする。

インストール先を変更した以外に、次のように設定した。

```
■ Modify password for database user 'root'
   xxxxx
  □ Enable access from remote machines for 'root' user
□ Create An Anonymous Account
■ Use UTF8 as default server's character set

■ Install as service
   Service Name: MySQL
■ Enable networking
   TCP port: 3306
■ Optimize for transaction
   Buffer pool size: 767MB

□ Enable the Feedback plugin and submit anonymous usage information

```

`c:\kamp\mariadb\bin` をシステム環境変数の PATH に追加しておく。

コマンド・プロンプトでアクセスしてみる。

```bat
mysql -uroot -pxxxxx
```

ログイン出来て、`show databases;` などのコマンドが動けば、オーケー。

デスクトップに "HeidiSQL" のショートカットが作成されるが、ゴミ箱にポイする。どうせ、phpMyAdmin を使うんだし ... と思っていたが、コメントで "HeidiSQL" は SSH トンネルで外部の MySQL にも繋げられることを教えてもらった。便利そうなので、使ってみることにする。

となると、phpMyAdmin は不要になるが、一応、設定の仕方を書いておく。


# phpMyAdmin #

[phpMyAdmin のサイト](https://www.phpmyadmin.net/) から、最新版 phpMyAdmin-5.1.0-all-languages.zip を取得して、`C:\kamp\phpMyAdmin` 以下に展開する。

phpMyAdmin 用の設定として `C:\kamp\Apache24\conf\extra\httpd-phpmyadmin.conf` を作成する。

```apache:httpd-phpmyadmin.conf
Alias /phpmyadmin /kamp/phpMyAdmin

<Directory /kamp/phpMyAdmin/>
   AddDefaultCharset UTF-8

   <IfModule mod_authz_core.c>
     # Apache 2.4
     Require local
   </IfModule>
</Directory>

<Directory /kamp/phpMyAdmin/setup/>
   <IfModule mod_authz_core.c>
     # Apache 2.4
     Require local
   </IfModule>
</Directory>
```

メインの `C:\kamp\Apache24\conf\httpd.conf` で上記をインクルードする。

```apache:httpd.conf
# for phpMyAdmin
Include conf/extra/httpd-phpmyadmin.conf
```

`index.html` に `phpmyadmin/index.php` へのリンクを追加して、動作を確認する。

とりあえず動くが、いろいろ文句を言われる。

## config.inc.php ##

`C:\kamp\phpMyAdmin\config.sample.inc.php` をコピーして `C:\kamp\phpMyAdmin\config.inc.php` を作成し、編集する。

```php:config.inc.php
$cfg['blowfish_secret'] = 'xxxxx'; /* 32文字 */
```

ランダムな文字列を生成するウェブ・サービスがあるので、それを使えば良い。

これだけで文句が少なくなるので、phpMyAdmin を使って作業を進めることが出来る。

`C:\kamp\phpMyAdmin\sql\create_tables.sql` をインポートして、phpmyadmin 用のデータベースを作成する。そして、作成したデータベースにアクセス可能なユーザを作成する。何も考えずに、アカウント:`pma`、パスワード:`pmapass` としたが、まあ、適当でよいだろう。

そして、これに合うように、config.inc.php を編集する。

```php:config.inc.php
/**
 * First server
 */
$i++;
/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'cookie';
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['compress'] = false;
$cfg['Servers'][$i]['AllowNoPassword'] = false;

/**
 * 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'] = 'pmapass';

/* Storage database and tables */
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
...
/* 以下、同様に、コメントを外す */
```

コンソールから MySQL (MariaDB) にログインして、ユーザ `pma` を作成する。

```
C:\kamp\Apache24\bin>mysql -uroot -p****
...
MariaDB [(none)]> create user 'pma'@'%' identified by 'pmapass';
Query OK, 0 rows affected (0.002 sec)

MariaDB [(none)]> grant all privileges on *.* to 'pma'@'%' with grant option;
Query OK, 0 rows affected (0.001 sec)
```

いや、それなら、`root` とそのパスワードを phpMyAdmin でも使えば良いのではないか、という話ではある。

以上で、phpMyAdmin は問題なく動くようになった。

# SSL #

## サーバ証明書の準備 ##

[easy-ca によるオレオレ認証局とオレオレ証明書](https://qiita.com/softark/items/cb92f1ebed8b4b6c55b4) に従って、`localhost` のためのオレオレ・サーバ証明書を準備する。

準備したサーバ証明書と鍵 (`oreore.crt` と `oreore.key`) は、`C:\kamp\Apache24\conf` に置く。


## httpd.conf の修正 ##

以下のモジュールを追加で有効にする。

```apache:httpd.conf
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule ssl_module modules/mod_ssl.so
```

SSL の設定ファイルを読み込むようにする。

```apache:httpd.conf
# Secure (SSL/TLS) connections
Include conf/extra/httpd-ssl.conf
```

## httpd-ssl.conf の修正 ##

サーバ証明書のファイル名を変更する。

```apache:httpd-ssl.conf
SSLCertificateFile "${SRVROOT}/conf/oreore.crt"
...
SSLCertificateKeyFile "{SRVROOT}/conf/oreore.key"
```

サーバを再起動し、`https://localhost/` にアクセスして、確認する。

# 残りの作業 #

いくらか作業が残っているが、まあ、もう良いだろう。

- バーチャル・ホストの設定
- `C:\kamp\Apache24\conf\httpd.conf` のチューニング
- `C:\kamp\php\php.ini` のチューニング