PHP7.3.6をCentOS6にソースインストール

覚書です。
ところどころ省いています。
実践環境で使う場合はご注意ください。

特徴

  • ソースコードからのインストール
  • 複数バージョンの共存

特定バージョンでの開発や動作確認など開発環境での用途を目的としています。

環境

実施日2019-6-21
サーバさくらのVPS 2G
OSCentOS 6.10
cat /etc/redhat-release
CentOS release 6.10 (Final)
rpm -qa | grep centos-release
centos-release-scl-7-4.el6.centos.noarch
centos-release-6-10.el6.centos.12.3.x86_64
centos-release-scl-rh-2-4.el6.centos.noarch

事前準備

PHP 7.3.6

/tmp/php-7.3.6.tar.gz

PHPダウンロードページからダウンロードして、/tmp にアップ

MySQL

事前にMySQLクライアントとして使うMySQLをインストールしておきます(インストール手順は別の記事で後日)

MySQLを使わない場合、他のデータベースを使う場合は、以降の configure を調整してください

libxml2

libxml2-2.9.9

PHP7.0.0からは 2.9.0 以上が良さそうです。
PHP Predefined Constants の 「Only available in Libxml」
ここにある定数を使わないなら古いバージョンでも動きます。

--with-libxml-dir=/usr/local/lib/libxml2-2.9.9

libzip

PHPをconfigureしていると次のエラーが発生しました。

configure: error: Please reinstall the libzip distribution

PHP7.3 からはlibzip の 0.11 以上が必須になったようです。

--with-libzip=/usr/local/lib/libzip-1.5.2/bin

インストール

設定

DIR_SOURCE=/tmp
PHP_VERSION=7.3.6
MYSQL_VERSION=5.5.27
MYSQL_TITLE=mysqlnd
MYSQL_CLIENT=mysqlnd
MYSQLI_CLIENT=mysqlnd
MYSQLPDO_CLIENT=mysqlnd

※MYSQL_VERSION は、独自にインストールしたMySQLを指定する場合に必要。YUM で入れた MySQL を使う場合は未指定でOK。

事前準備

# /usr/local/src にディレクトリを作る
mkdir /usr/local/src/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE

# ↑で作ったディレクトリに移動
cd /usr/local/src/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE

# /tmp にアップしておいた tar.gz を移動
cp $DIR_SOURCE/php-$PHP_VERSION.tar.gz /usr/local/src/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php-$PHP_VERSION.tar.gz

# 解凍
tar xzf php-$PHP_VERSION.tar.gz

# 解凍先に移動
cd php-$PHP_VERSION

--with-imap を付ける場合

yum install libc-client-devel

--with-mcrypt を付ける場合

yum install libmcrypt-devel

configure

./configure \
--prefix=/usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE \
--program-suffix=-$PHP_VERSION-mysqlc-$MYSQL_TITLE \
--with-config-file-path=/usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE \
--with-libdir=lib64 \
--with-pic \
--with-curl \
--with-freetype-dir=/usr \
--with-png-dir=/usr \
--with-jpeg-dir=/usr \
--with-gettext \
--with-iconv \
--with-layout=GNU \
--with-kerberos \
--with-unixODBC=shared,/usr \
--with-libxml-dir=/usr/local/lib/libxml2-2.9.9 \
--with-gd \
--with-zlib \
--with-mysqli=$MYSQLI_CLIENT \
--with-pdo-mysql=$MYSQLPDO_CLIENT \
--with-mysql-sock=/var/lib/mysql/mysql.sock \
--with-openssl \
--with-libzip=/usr/local/lib/libzip-1.5.2 \
--without-pear \
--enable-cgi \
--enable-mbstring \
--enable-cli \
--enable-zip \
--enable-exif \
--enable-ftp \
--enable-sockets \
--enable-sysvsem \
--enable-sysvshm \
--enable-sysvmsg \
--enable-wddx \
--enable-shmop \
--enable-calendar \
--enable-opcache \
--enable-intl \
--disable-debug
libxml2 にyumインストールしたものを使うなら(バージョン古い)
--with-libxml-dir=/usr

imap を使うなら
--with-imap=/usr
--with-imap-ssl

mcrypt を使うなら
--with-mcrypt

soap を使うなら
--enable-soap

バグ修正

configure が無事完了して安心していたところ、make の最中に次のエラーが発生しました。

main/internal_functions_cli.c:70 から include されたファイル中:
/usr/local/src/php-7.3.6-mysqlc-mysqlnd/php-7.3.6/ext/zip/php_zip.h:31:17: error: zip.h: そのようなファイルやディレクトリはありません
In file included from main/internal_functions_cli.c:70:
/usr/local/src/php-7.3.6-mysqlc-mysqlnd/php-7.3.6/ext/zip/php_zip.h:54: error: field ‘sb’ has incomplete type
make: *** [main/internal_functions_cli.lo] エラー 1

zip.h が見つからないとのことです。

ls -la /usr/include/z*

確かにありません。
--with-libzip=/usr/local/lib/libzip-1.5.2
を指定しているので、ここもインクルードパスに入っていると思い込んでいたのですが、そうではなかったようです。

/usr/local/lib/libzip-1.5.2/include の内容を /usr/include にコピーするとかシンボリックリンクするとかしても良いのですが、将来的なことを考えると良い方法ではないかもしれません。

そこで次の2カ所を編集します。

vi ./ext/zip/php_zip.h
31行目
- #include <zip.h>
+ #include "/usr/local/lib/libzip-1.5.2/include/zip.h"
vi /usr/local/lib/libzip-1.5.2/include/zip.h
45行目
- #include <zipconf.h>
+ #include "/usr/local/lib/libzip-1.5.2/include/zipconf.h"

今回は、libzip を独自の場所にインストールしたためインクルードパスに含まれてなかったことが原因です。
レアケースだと思います。

余談

エラーを調査していくと、別の理由で同じエラーになることが分かりました。

まずはこちら
https://www.php.net/manual/ja/zip.installation.php
PHP 5.6.0 から、--with-libzip=DIR オプションが追加されています。

次にこちら
https://bugs.php.net/bug.php?id=76345
私の場合と同じようなエラー内容での報告です。

Gitにコミットされたのが「Tue, 28 May 2019 00:42:20 +0900」なのですごく最近(PHP7.3.6は2019-05-30リリース)になって解決されたようです。

修正された個所はこちら

実は今回私が遭遇したのは「エラーメッセージは同じだけど原因は異なる」でした。
いろいろ調査したりパッチを当てたりしても解決しなかったのは「そもそも /usr/include に zip.hを置いてなかった」からでした。

インストール

make
make test
make install

パスを通す

# セット
echo 'PATH=$PATH:'"/usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE"/bin >> /etc/profile.d/php.sh
echo "export PATH" >> /etc/profile.d/php.sh

# 確認
cat /etc/profile.d/php.sh

# 反映
source /etc/profile.d/php.sh

php.iniを設定

# php.ini-development を php.ini としてコピーして配置
cp /usr/local/src/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php-$PHP_VERSION/php.ini-development /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini

# タイムゾーンを Asia/Tokyo に変更
sed -i -e "s/^;date\.timezone =[^A-Za-z]*$/date.timezone =/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini
sed -i -e "s/^date\.timezone =[^A-Za-z]*$/date.timezone = Asia\/Tokyo/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini

次の3つの .sock は yum でMySQLをインストールした場合の位置
# sed -i -e "s/^mysql\.default_socket =$/mysql.default_socket = \/var\/lib\/mysql\/mysql.sock/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini
# sed -i -e "s/^mysqli\.default_socket =$/mysqli.default_socket = \/var\/lib\/mysql\/mysql.sock/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini
# sed -i -e "s/^pdo_mysql\.default_socket=$/pdo_mysql.default_socket = \/var\/lib\/mysql\/mysql.sock/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini

OPcacheの設定 (公式のデフォルトで設定)
http://php.net/manual/ja/opcache.installation.php
# sed -i -e "s/^;opcache.memory_consumption=/opcache.memory_consumption=/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini
# sed -i -e "s/^;opcache.interned_strings_buffer=/opcache.interned_strings_buffer=/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini
# sed -i -e "s/^;opcache.max_accelerated_files=/opcache.max_accelerated_files=/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini
# sed -i -e "s/^;opcache.revalidate_freq=/opcache.revalidate_freq=/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini
# sed -i -e "s/^;opcache.enable_cli=/opcache.enable_cli=/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini

vi /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini
opcache.fast_shutdown=1
が無いと思うので [curl] の上あたりに追記する
# mysql をソースからインストールしている場合はこちら
sed -i -e "s/^mysql\.default_socket =$/mysql.default_socket = \/var\/lib\/mysql\/mysql.sock/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini
sed -i -e "s/^mysqli\.default_socket =$/mysqli.default_socket = \/var\/lib\/mysql\/mysql.sock/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini
sed -i -e "s/^pdo_mysql\.default_socket=$/pdo_mysql.default_socket = \/var\/lib\/mysql\/mysql.sock/g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php.ini

確認

# php.iniのタイムゾーン
grep -E 'date.timezone|default_socket' /usr/local/lib/php-7.3.6-mysqlc-mysqlnd/php.ini

# php.ini
vi /usr/local/lib/php-7.3.6-mysqlc-mysqlnd/php.ini

バージョン

php-7.3.6-mysqlc-mysqlnd -v
PHP 7.3.6 (cli) (built: Jun 22 2019 01:33:28) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.6, Copyright (c) 1998-2018 Zend Technologies

あとがき

mysqlnd について
昔はMySQLクライアントを複数から選択できていたので、「php-バージョン-mysqlc-クライアント」のようにしていたけど、もうmysqlnd一択みたいな感じなので名前に入れなくても良いかなと思います。
詳しくはこのあたり