Raspberry PiでApache2.4＋PHP7.4をソースコンパイルしてWebサーバー構築 - 2.PHP導入編

# 前提と準備

## Linuxサーバー構築の記事
- [Sambaでファイルサーバー構築(CentOS 8.1・openSUSE 15.1・Ubuntu 20.04)](https://qiita.com/kazumi75kitty/items/4298795029ba9f67b9d2)
- [LinuxでApache2.4＋PHP7.4をソースコンパイル - 1.Apache導入](https://qiita.com/kazumi75kitty/items/daaf8ff8feb50ad04f41) /[【Raspberry Pi】](https://qiita.com/kazumi75kitty/items/67686eccaaec73251458)
- [LinuxでApache2.4＋PHP7.4をソースコンパイル - 2.PHP導入](https://qiita.com/kazumi75kitty/items/fca116b1b387fe56c93c) /【Raspberry Pi：この記事】
- [LinuxでApache2.4＋PHP7.4をソースコンパイル - 3.MySQL導入](https://qiita.com/kazumi75kitty/items/76807c637c096618a0e1) /[【Raspberry Pi】](https://qiita.com/kazumi75kitty/items/4212dacc45944f27ca94)
- [LinuxでApache2.4＋PHP7.4 - 4.セキュリティ(chownとfirewalld)](https://qiita.com/kazumi75kitty/items/8ad51806ac50bd04b644)
- [LinuxでIPsecゲートウェイをVPN構築 - 1.StrongSwan導入](https://qiita.com/kazumi75kitty/items/60941f00ae91c4d9f555) /[【Ubuntu 20.04＋Raspberry Pi】](https://qiita.com/kazumi75kitty/items/08259681247a6c2ebd0d)
- [LinuxでIPsecゲートウェイをVPN構築 - 2.VPNへの接続確認](https://qiita.com/kazumi75kitty/items/f5a33abda9f8edd5c47f) /[【Ubuntu 20.04＋Raspberry Pi】](https://qiita.com/kazumi75kitty/items/c83f920f052d83d62457)

[前回](https://qiita.com/kazumi75kitty/items/67686eccaaec73251458)はApache httpd 2.4.46をソースコンパイルでRaspberry Piに構築しましたが、今回は、前回に引き続き、ApacheにWebアプリサーバーの基幹であるPHP 7.4をソースコンパイルで導入します(⑅•ᴗ•⑅)

## 環境
- Webサーバープログラム：Apache 2.4.46 ＋ PHP 7.4.10(ソースコンパイル)
- クライアント：Windows10 Pro
- サーバーのアーキテクチャ：Raspberry Pi 3B+(armv8搭載) Linuxのディストリビューション：openSUSE 15.1 Leap(64bit) / Raspberry Pi OS 2020.08版(32bit)

## 前提
- ユーザーはrootでインストール(私の検証ではadminという管理者アカウントにて、そこからsudoで処理しています)
- openSUSEではファイアウォールはfirewalldを使う(ディストリビューション独自のファイアウォールコマンドは使用しない)。ラズパイのRaspberry Pi OSでは、firewalldについて、IPv6周りの連動が糞だったので、Debian系標準のufwを使用することにしました。
- [前回](https://qiita.com/kazumi75kitty/items/67686eccaaec73251458)の記事のApache導入を完了していること(動作が確認できて、Webサーバーとして構築されていること)

## サーバー条件
### IPアドレス
- クライアント：192.168.1.11
- Webサーバー：192.168.1.18(どのディストリビューションでも同じIPアドレスで検証)
- 所属ネットワークセグメント：192.168.1.0/24
![Webサーバー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/a7610e28-afe4-2724-d772-8e45a4b1931e.png "Webサーバーとクライアントのネットワーク図")

### パッケージを個別ダウンロードしてインストールする機能とバージョン(2020年6月時点)
- zlib-1.2.11.tar.gz
- apr-1.7.0.tar.gz
- apr-util-1.6.1.tar.gz
- httpd-2.4.46.tar.gz
- php-7.4.10.tar.gz

それ以外の必要なパッケージは、ディストリビューションの標準パッケージコマンド(dnfやaptなど)でインストールし、個別ダウンロードは不要です。

ダウンロードについては、公式サイトにアクセスして、そこからダウンロードしてFTPで転送するか、ダウンロードファイルのURLさえわかれば、wgetで入手することもできますが、入手方法は省略しています。

# 作業手順
## PHPのインストール
### PHPのソースコンパイルに必要なライブラリを導入

```openSUSE15.1(RaspberryPi)
# zypper -n install libxml2-tools libxml2-devel sqlite3-devel oniguruma-devel
```

```RaspberryPiOS(2020.08)
# apt-get -y install libxml2 libxml2-dev libsqlite3-dev libonig-dev
```

PHP7.3までは、SQLiteと鬼車のライブラリを使わなくてもマルチバイト文字列を扱うようインストールができたのですが、PHP7.4ではソースコンパイルで必須となりました。

### PHPのソースコンパイル(実際swap仮想メモリ不足で強制終了しハマった)
コンパイルには30～40分前後かかる見込みです。Apacheより規模が大きいので、コンパイル中はコーヒー1杯で休憩をはさんだほうがいいかもしれません(\*˘︶˘\*).｡.:\*♡

```
# cd [php-7.4.10.tar.gzが置いてあるディレクトリ]
# tar xvzf php-7.4.10.tar.gz
# cd php-7.4.10/
# ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysqli --with-pdo-mysql --enable-mbregex --enable-mbstring
# make
# make test
```

- MySQLはPDOを有効にします
- マルチバイト文字列を有効にします

「make」「make test」が時間がかかるコマンドです。
途中でエラーがなければコンパイル完了ですが、**そこでRaspberry Pi OSのほうで問題発生。**

```RaspberryPiOS(2020.08)
# make

/bin/bash /home/admin/php-7.4.10/libtool --silent --preserve-dup-deps --mode=compile cc -I/home/admin/php-7.4.10/ext/fileinfo/libmagic -Iext/fileinfo/ -I/home/admin/php-7.4.10/ext/fileinfo/ -DPHP_ATOM_INC -I/home/admin/php-7.4.10/include -I/home/admin/php-7.4.10/main -I/home/admin/php-7.4.10 -I/home/admin/php-7.4.10/ext/date/lib -I/usr/include/libxml2 -I/home/admin/php-7.4.10/ext/mbstring/libmbfl -I/home/admin/php-7.4.10/ext/mbstring/libmbfl/mbfl -I/usr/local/include -I/home/admin/php-7.4.10/TSRM -I/home/admin/php-7.4.10/Zend  -D_REENTRANT -pthread  -I/usr/include -g -O2 -fvisibility=hidden -pthread -Wall -Wno-strict-aliasing -DZTS -DZEND_SIGNALS   -c /home/admin/php-7.4.10/ext/fileinfo/libmagic/apprentice.c -o ext/fileinfo/libmagic/apprentice.lo
cc: fatal error: 強制終了 signal terminated program cc1
compilation terminated.
make: *** [Makefile:738: ext/fileinfo/libmagic/apprentice.lo] エラー 1
```

こんなふうにmake中で強制終了してしまった(´•ω•̥`)
PHPは相当の処理の多さでビルドするので、Raspberry Pi OSだけなぜ…と思いつつ、メモリの空き容量を調べてみたら…

```RaspberryPiOS(2020.08)
# free
              total        used        free      shared  buff/cache   available
Mem:         948072      389256      367752       99504      191064      394740
Swap:        102396      102256         140
```
Raspberry Pi OSではたったの100MBしかswap領域がなかったことに気が付いて、空きが1MBだけ…(openSUSEはRaspberry Piでも400MBはあった)

なので、swap領域を増やして仮想メモリを増やすことにした。**Raspberry Pi OSでは、swapはパーテーションではなくdphys-swapfileで定義**される

- 参照：[パイ・スワップの増量](https://goozenlab.com/blog/2019/08/pi-swap-dphys/)

```RaspberryPiOS(2020.08)
# vi /etc/dphys-swapfile
CONF_SWAPSIZE=100		← 増量する
CONF_SWAPFACTOR=2		← 倍率を設定する

# reboot
```

私の場合は200MBに増量して、倍率を2に設定しました。
再起動して再ビルドし、今度こそうまく成功しました！！
【でも実際は再起動したことによってビルドがうまくいったっぽい】

しかし**さらなる問題が発生した**。
今度は「make test」でSegmentation Faultとなってしまう事象が発生している。ビルドは成功したはずなのに、テストがセグメンテーション違反(Windowsでいうアプリケーションエラーと呼ばれている)でクラッシュする事象が発生。。。

テストツールに問題があるのか、ビルドしたモジュールに問題があるのか、今回のところはとりあえずPHPを動かして調べてみることにするので、テストはいったん保留。

### PHPのインストール
コンパイルが完了したら、インストールします。

```
# make install
Installing PHP SAPI module:       apache2handler
/usr/local/apache2/build/instdso.sh SH_LIBTOOL='/opt/apr-1.7.0/build-1/libtool' libphp7.la /usr/local/apache2/modules
/opt/apr-1.7.0/build-1/libtool --mode=install install libphp7.la /usr/local/apache2/modules/
libtool: install: install .libs/libphp7.so /usr/local/apache2/modules/libphp7.so
libtool: install: install .libs/libphp7.lai /usr/local/apache2/modules/libphp7.la
libtool: warning: remember to run 'libtool --finish /home/admin/php-7.4.6/libs'
chmod 755 /usr/local/apache2/modules/libphp7.so
[activating module `php7' in /usr/local/apache2/conf/httpd.conf]
Installing shared extensions:     /usr/local/lib/php/extensions/no-debug-zts-20190902/
Installing PHP CLI binary:        /usr/local/bin/
Installing PHP CLI man page:      /usr/local/php/man/man1/
Installing phpdbg binary:         /usr/local/bin/
Installing phpdbg man page:       /usr/local/php/man/man1/
Installing PHP CGI binary:        /usr/local/bin/
Installing PHP CGI man page:      /usr/local/php/man/man1/
Installing build environment:     /usr/local/lib/php/build/
Installing header files:          /usr/local/include/php/
Installing helper programs:       /usr/local/bin/
  program: phpize
  program: php-config
Installing man pages:             /usr/local/php/man/man1/
  page: phpize.1
  page: php-config.1
/home/admin/php-7.4.6/build/shtool install -c ext/phar/phar.phar /usr/local/bin
ln -s -f phar.phar /usr/local/bin/phar
Installing PDO headers:           /usr/local/include/php/ext/pdo/
```

PHPのライブラリのいくつかは「/usr/local/include/php/」「/usr/local/lib/php/」のように、用途に応じて複数の配置場所へ配置されます。しかも**今回PHP 7.4.10は、ラズパイのopenSUSEでも「/usr/local/lib64/php/」に配置されるのではなく、他のディストリビューションと同じ配置になったんです**。なぜだかは知らないが、とりあえずPHP 7.4.10＋openSUSE 15.1をラズパイで実装すると、lib64に配置されずlibディレクトリに配置されることがわかったんです。

また、この時点で、**PHPのDLL(ダイナミックリンクライブラリ、外部拡張アプリケーションに該当する)は自動的にApacheのフォルダに配備されます**。

次に、PHPの環境設定ファイルのコピーを行います。
まずはphp.iniをPHPのライブラリフォルダ/usr/local/lib(openSUSEも含む)/にコピーします。

```
# cp php.ini-development /usr/local/lib/php.ini
# ls -l /usr/local/lib
合計 328
-rw-r--r-- 1 root root 144402  6月 24 12:34 libz.a
lrwxrwxrwx 1 root root     14  6月 24 12:34 libz.so -> libz.so.1.2.11
lrwxrwxrwx 1 root root     14  6月 24 12:34 libz.so.1 -> libz.so.1.2.11
-rwxr-xr-x 1 root root 113656  6月 24 12:34 libz.so.1.2.11
drwxr-xr-x 4 root root     37  6月 24 16:19 php
-rw-r--r-- 1 root root  72278  6月 24 16:21 php.ini
drwxr-xr-x 2 root root     21  6月 24 12:34 pkgconfig
```

### Apache側の設定
Apacheで、PHPファイルが認識できるようにする必要があるので編集します。PHPのDLLは、PHPインストール時にhttpd.confで自動的に書き込まれるので追加不要です。httpd.conf側でやるべきことは、PHPのMIMEタイプがApacheで認識されればよいのです。

```
# vi /usr/local/apache2/conf/httpd.conf
```

```xml:/usr/local/apache2/conf/httpd.conf
…
<IfModule dir_module>
    DirectoryIndex index.html　← 「index.php」を追加
</IfModule>
…
<IfModule mime_module>
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
    …
    AddType application/x-httpd-php .php  ←   この行を追加
</IfModule>
…
```

### PHPの環境設定
PHPの文字コードや参照ライブラリの設定を変えます。

```
# vi /usr/local/lib/php.ini
```

```ini:php.ini
# 内容が長いので、一部修正するもののみ、修正後のもののみを記載します。セミコロン「;」は外します。「;」外すだけの行も含めて記載されています
output_buffering = On
default_charset = "UTF-8"
include_path = ".:/usr/local/include/php:/usr/local/lib/php"
extension_dir = "/usr/local/include/php/ext"
date.timezone = Asia/Tokyo
mbstring.language = Japanese
mbstring.encoding_translation = Off
mbstring.detect_order = UTF-8, SJIS, EUC-JP, JIS, ASCII
mbstring.substitute_character = none
```

## PHPの動作確認
### PHP確認用のページ
まずは確認用のPHPページを作ります。

```
# vi /usr/local/apache2/htdocs/phpi.php
```

```php:phpi.php
<?php phpinfo(); ?>
```

なぜPHPファイルを/usr/local/apache2/htdocs/に配置する？？って聞かれますが、Apacheをソースコンパイルでインストールすると、Webページデータの格納フォルダは「/usr/local/apache2/htdocs/」がデフォルトだからです。まぁ、httpd.confで格納先を変更できますが、今回はそれは割愛します。

### Apacheの再起動

```
# systemctl stop httpd
# systemctl start httpd
# systemctl status httpd
```
再起動しないとPHPのモジュールをロードした状態でApacheが動作しないので、一度止めてから、再スタートします。その後、statusで起動していることを確認します。
![phpinfo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/2b6b4331-954a-f90f-1338-ab07b7b7c61c.png "PHPが認識できた！！")

![pdo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617906/56400b99-ffef-a001-7e85-05fbb766dc93.png "PDOも使える！！")

上の画像は仮想マシンのものですが、Raspberry Piでも同じようなphpinfoが表示されたので、PHPは使えるようになりました(\*˘ᗜ˘\*)
…ただ単に画像の用意が面倒だからやってないだけなんで。。。

# 次回
MySQLに接続して、PHPのWebアプリサーバーがデータベースを利用できるようにします。**ラズパイではMySQLはサポートされていない**ので、レポジトリから直接簡単インストールすることはできず、インストールしたとしても、microSDの書き込み寿命を縮めるだけなので、次回は**MySQLサーバーに接続できるか**を検証します。