XAMPPのPHPのバージョンをアップグレードする ( 7.1.7 → 7.4.3 )

Windows 10のXAMPP環境でcomposer.jsonでパッケージをインストールしようとしたところ、「パッケージを入れようとしたが、環境のPHPのバージョンが古くて入れられなかったよ」という旨のエラーメッセージが出てしまって先に進めなくなりました(エラーメッセージを控えるのを失念していたため正確なメッセージはなし)。

確かにエラーを出しているパッケージはrequireのところにphp >= 7.2と書いてありますが、今回試した環境はphp 7.1.7……はい、足りません。

ということでPHPのみアップグレードをしようとしたのですが、途中上手く行かず紆余曲折した上に、検索した限りではここまでこじれている事例が見当たらなかったのでメモしておきます。

DockerやVagrantも使いたいのですが、リソースが限られているので今回はXAMPP……。

手順

PHPのみのアップグレードは基本、PHP本体をダウンロードしてきて配置するだけです。私もその予定でした。

上述ページから現時点で最新のPHP 7.4 (7.4.3)をダウンロードします。

PHPのページでダウンロードする
PHPのページでダウンロードする

XAMPPはPHPが32bit版という話を検索すると何件かヒットしたので、スレッドセーフな32bit版(VC15 x86 Thread Safe (2020-Feb-18 22:57:31))のzipをダウンロードします。

ひとまずzipは解凍。

実際に置き換える作業を行う前にXAMPPのコントロールパネルからApacheを停止します。

次に、新しいバージョンのPHPで置き換えるために現在のPHPを退避させます。

今回はD:\直下にXAMPPがいる環境なので、PHPのパスはD:\xampp\phpとなります。
このディレクトリをD:\xampp\php-717にリネームしました。

それから、先ほど解凍したphp-7.4.3-Win32-vc15-x86をディレクトリごとD:\xampp\にコピーしてきて、D:\xampp\php-7.4.3-Win32-vc15-x86D:\xampp\phpにリネームします。

XAMPP内のPHPディレクトリを置き換えた図
XAMPP内のPHPディレクトリを置き換えた図

これで置き換え完了。

XAMPPのApacheを起動してみます。

ここからトラブルシューティング

トラブル1: Apacheが起動しない

……が、エラーでコケました。

HH:ii:ss [Apache] Error: Apache shutdown unexpectedly. HH:ii:ss [Apache] This may be due to a blocked port, missing dependencies, HH:ii:ss [Apache] improper privileges, a crash, or a shutdown by another method. HH:ii:ss [Apache] Press the Logs button to view error logs and check HH:ii:ss [Apache] the Windows Event Viewer for more clues HH:ii:ss [Apache] If you need more help, copy and post this HH:ii:ss [Apache] entire log window on the forums

ただしXAMPPのコントロールパネルに表示されるこのエラーメッセージはあまりアテにならないので「エラーが起きた」程度の情報で留めておくと良さそうです。

対処1.1: dllを置換する

慌てずXAMPP の PHP だけをアップデートする | Thought is freeの記事の対処を実施してみます。

いったんD:\xampp\apache\binに存在するdllをD:\xampp\apache\bin\old_dllに退避した上で、どのdllを新しくする必要があるのか確認するために、仮で先ほどコピーしてきたD:\xampp\phpの中にあるdllファイルを全てコピーしようと試みます。

すると、以下の3つのdllファイルが競合していると分かりました。

競合しているdll
競合しているdll
  • libsasl.dll
  • libssh2.dll
  • nghttp2.dll

いったんコピーの実行は全てキャンセルし、今挙げた3つのファイルのみD:\xampp\phpからD:\xampp\apache\binに上書きコピーします。

競合している3つのdllのみコピー
競合している3つのdllのみコピー

これで再度Apacheの起動を試みますが……ダメでした。

対処1.2: vcruntime140.dllの入手1(「Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ」のインストール→失敗)

上述の参考記事の対処で直らなかったのでここからは手探りで対処を行うことにします。

まずはXAMPPコントロールパネルのApacheの「Logs」ボタンから「Apache (error.log)」を選択し、エラーログを確認します。

すると、アップグレード作業前の正常に起動できていたときには出ていなかった警告が出ていました。

PHP Warning: ‘vcruntime140.dll’ 14.0 is not compatible with this PHP build linked with 14.16 in Unknown on line 0

vcruntime140.dllがないことで起動が失敗しているようです。

入手するためには「Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ」をインストールすれば良いらしいので、これを試します。

ちなみに上述のエラーメッセージで検索すると「Visual Studio 2017 の Microsoft Visual C++ 再頒布可能パッケージ」をインストールするように紹介する記事がヒットしますが、Microsoftの最新のサポートされる Visual C++ のダウンロードの記事を読むと以下のように記されています。

注: Visual C++ 2015、2017、および 2019 はすべて同じ再頒布可能ファイルを共有します。 最新のサポートされる Visual C++ のダウンロード

この文章から、「Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ」をインストールしても問題はないと判断しました。

まずは上述のリンクにアクセスし、「その他のツールとフレームワーク」のプルダウンを展開し、「Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ」の欄の右側で「x86」、「日本語」を選択した上で「ダウンロード」をクリック。

「Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ」のダウンロード
「Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ」のダウンロード

ダウンロードが完了したらexeを実行し、インストールを実行します。

「Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ」のインストール
「Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ」のインストール

再起動要求が来たら再起動。

インストールが完了したので、再々度Apacheを起動……ダメでした。

対処1.3: vcruntime140.dllの入手2(vcruntime140.dllファイルをコピー)

依然として

PHP Warning: ‘vcruntime140.dll’ 14.0 is not compatible with this PHP build linked with 14.16 in Unknown on line 0

の警告がログに出続けているので、vcruntime140.dllD:\xampp\apache\binに置かないとダメなのではないか、と推測。

そこでvcruntime140.dllを探しますが……ない。

C全体でvcruntime140.dllを検索しますが、Visual Studio 2019関連のディレクトリすら見当たりません。

C全体で`vcruntime140.dll`を検索した結果
C全体で`vcruntime140.dll`を検索した結果

もしやパッケージ内に格納されているか、cab等の別の形式で存在しているか……と途方に暮れていたのですが、ダメ元で先ほど検索結果に最新でヒットしたEdgeの中のvcruntime140.dllを持ってくることにしました。

ちなみに今回の環境はEdgeはChromium Edgeに変更済みです。その環境で先ほどの検索結果の場所C:\Program Files (x86)\Microsoft\Edge\Application\80.0.361.57に移動し、vcruntime140.dllをコピーそしてD:\xampp\apache\binにペースト(既存ファイルを上書き)。

これでApacheを起動……起動しました

いくらランタイムとはいえ「目に付いた中で最新のバージョンと思われるランタイムを別アプリケーションから間借りしてきた」という雑な方法で動くとは思いませんでした。

`localhost/dashboard/phpinfo.php`を表示した様子
`localhost/dashboard/phpinfo.php`を表示した様子

localhost/dashboard/phpinfo.phpにアクセスすると……確かに7.4.3ですね。

これで解決、かと思いきや。

トラブル2: MySQLに接続できない

ローカルで動かしているアプリにアクセスすると、例外が投げられており、以下のエラーメッセージが表示されていました。

could not find driver

ドライバーがない……だと……。

今回のケースではphp-mysqlphp-pdo辺りが怪しいですが、D:\xampp\php\extを確認するとphp_mysqli.dllphp_pdo_mysql.dllがファイルとして存在しているため、モジュール読み込みが怪しいと推測。

php.iniはどうなっているのかとD:\xampp\phpの中を確認したところ……php.ini-developmentphp.ini-productionという開発・本番それぞれ用のテンプレはありましたが、php.iniそのものは存在していませんでした。

対処2.1: php.iniの移植

そこで、Apacheをいったん停止させて、退避したD:\xampp\php-717からphp.iniD:\xampp\phpにコピーしてapacheの起動を試みました。しかし、エラーで起動できませんでした。

対処2.2: 新しいバージョン用のphp.iniを作る

仕方ないので、設定ファイルを新しく作ることにします。

php.ini-developmentをコピーしてphp.iniにリネームし、このファイルとD:\xampp\php-717\php.iniの差分を比較しながら記述を修正していきます。

;extension=bz2
;extension=curl
;extension=ffi
;extension=ftp
;extension=fileinfo
;extension=gd2
;extension=gettext
;extension=gmp
;extension=intl
;extension=imap
;extension=ldap
;extension=mbstring
;extension=exif      ; Must be after mbstring as it depends on it
;extension=mysqli
;extension=oci8_12c  ; Use with Oracle Database 12c Instant Client
;extension=odbc
;extension=openssl
;extension=pdo_firebird
;extension=pdo_mysql
;extension=pdo_oci
;extension=pdo_odbc
;extension=pdo_pgsql
;extension=pdo_sqlite
;extension=pgsql
;extension=shmop

確認したところ、モジュール読み込みの部分が全てコメントアウトされていました。これを以下のように修正。

extension=bz2
extension=curl
;extension=ffi
;extension=ftp
;extension=fileinfo
extension=gd2
extension=gettext
;extension=gmp
;extension=intl
;extension=imap
;extension=ldap
extension=mbstring
extension=exif      ; Must be after mbstring as it depends on it
extension=mysqli
;extension=oci8_12c  ; Use with Oracle Database 12c Instant Client
;extension=odbc
extension=openssl
;extension=pdo_firebird
extension=pdo_mysql
;extension=pdo_oci
;extension=pdo_odbc
;extension=pdo_pgsql
extension=pdo_sqlite
;extension=pgsql
;extension=shmop

また、MySQLやPDOに関連する部分も修正。

[Pdo]
pdo_mysql.default_socket="MySQL" ;追記

[Pdo_mysql]
pdo_mysql.cache_size=2000 ;追記
; Default socket name for local MySQL connects.  If empty, uses the built-in
; MySQL defaults.
pdo_mysql.default_socket=
[MySQLi]

; Maximum number of persistent links.  -1 means no limit.
; http://php.net/mysqli.max-persistent
mysqli.max_persistent = -1

; Allow accessing, from PHP's perspective, local files with LOAD DATA statements
; http://php.net/mysqli.allow_local_infile
;mysqli.allow_local_infile = On

; Allow or prevent persistent links.
; http://php.net/mysqli.allow-persistent
mysqli.allow_persistent = On

; Maximum number of links.  -1 means no limit.
; http://php.net/mysqli.max-links
mysqli.max_links = -1

mysqli.cache_size=2000 ;追記
[MySQL]
mysql.allow_local_infile=On
mysql.allow_persistent=On
mysql.cache_size=2000
mysql.max_persistent=-1
mysql.max_link=-1
mysql.default_port=3306
mysql.default_socket="MySQL"
mysql.connect_timeout=3
mysql.trace_mode=Off

末尾に大量に追記されていたのでこれもそのまま追記。

ついでなのでphp.iniの冒頭の方にあったエラーメッセージの制御に関する設定も変更しておきます。

;error_reporting = E_ALL
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

これでApacheを起動すると、今度は起動してきました。

しかし、

could not find driver

このエラーメッセージは変わりませんでした。なんでさ。

対処2.3: php.iniの編集(その2)

PHPのバージョンを確認しようとすると警告が出ることがある、ということが参考記事を読んで分かりました。

そこで、試しにphp -vしてみます。

> php -v
PHP Warning:  PHP Startup: Unable to load dynamic library 'bz2' (tried: C:\php\ext\bz2 (指定されたモジュールが見つかりません。, C:\php\ext\php_bz2.dll (指定されたモジュールが見つかりません。) in Unknown on line 0

Warning: PHP Startup: Unable to load dynamic library 'bz2' (tried: C:\php\ext\bz2 (指定されたモジュールが見つかりません。, C:\php\ext\php_bz2.dll (指定されたモジュールが見つかりません。) in Unknown on line 0

※実際のコンソールでは「指定されたモジュールが見つかりません。」の部分は「謖~~~縺帙s縲」のように化けてしまっていましたが、検索したりエンコードで比較したりして元メッセージを推測しました。

この警告から、先ほどのモジュール読み込みの設定は、「読み込め」という設定自体は有効にはなっているものC:\php\ext\php_bz2.dllというパスが示している通り、読み込み先のパスがおかしいことが分かりました。

そこで、再びApacheを停止してphp.iniに以下の設定を追加。

;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories ;
;;;;;;;;;;;;;;;;;;;;;;;;;

;; 略

; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
;extension_dir = "./"
; On windows:
;extension_dir = "ext"
extension_dir = "ext" ;コメントを外す

これでApacheを起動。

> php -v
PHP 7.4.3 (cli) (built: Feb 18 2020 17:32:19) ( ZTS Visual C++ 2017 x86 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies

警告が消えました!

この状態で再度アプリケーションにアクセスすると、正常に動作しました!

まとめ

  • XAMPPのPHPのアップグレードは、基本的にはWindows用のPHPをダウンロード、XAMPP下にコピーすればOK
  • Apacheが起動できない場合は以下を確認
    • Apache下のdllファイル
    • vcruntime140.dllを新しくする
  • MySQLに接続するために
    • php.iniを作成
    • php.iniのモジュール読み込み設定を確認、パスがC直下ではない場合はextのパスも確認

紆余曲折ありましたが、何とかアップグレードに成功しました。

実は過去にも同環境で2度ほどアップグレードを試みたことがあるのですが、いずれも挫折していました。

今回ようやく成功した形になります……長かった……。

課題

PHPのバージョンのみアップグレードしたので、XAMPP同梱のphpMyadminから警告が出るようになってしまいました。

警告を無視すれば使えはしますが、こちらも要調整と思われます。

参考

PHPのみのアップグレード手順

vcruntime140.dll関連

MySQLに接続できない・モジュールが読み込まれていない関連

エラーメッセージの文字化け関連

差分比較ソフト(例)

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。