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)
をダウンロードします。
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-x86
をD:\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ファイルが競合していると分かりました。
libsasl.dll
libssh2.dll
nghttp2.dll
いったんコピーの実行は全てキャンセルし、今挙げた3つのファイルのみD:\xampp\php
からD:\xampp\apache\bin
に上書きコピーします。
これで再度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」、「日本語」を選択した上で「ダウンロード」をクリック。
ダウンロードが完了したらexeを実行し、インストールを実行します。
再起動要求が来たら再起動。
インストールが完了したので、再々度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.dll
をD:\xampp\apache\bin
に置かないとダメなのではないか、と推測。
そこでvcruntime140.dll
を探しますが……ない。
C全体でvcruntime140.dll
を検索しますが、Visual Studio 2019関連のディレクトリすら見当たりません。
もしやパッケージ内に格納されているか、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
にアクセスすると……確かに7.4.3ですね。
これで解決、かと思いきや。
トラブル2: MySQLに接続できない
ローカルで動かしているアプリにアクセスすると、例外が投げられており、以下のエラーメッセージが表示されていました。
could not find driver
ドライバーがない……だと……。
今回のケースではphp-mysql
やphp-pdo
辺りが怪しいですが、D:\xampp\php\ext
を確認するとphp_mysqli.dll
やphp_pdo_mysql.dll
がファイルとして存在しているため、モジュール読み込みが怪しいと推測。
php.ini
はどうなっているのかとD:\xampp\php
の中を確認したところ……php.ini-development
とphp.ini-production
という開発・本番それぞれ用のテンプレはありましたが、php.ini
そのものは存在していませんでした。
対処2.1: php.ini
の移植
そこで、Apacheをいったん停止させて、退避したD:\xampp\php-717
からphp.ini
をD:\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
を新しくする
- Apache下の
- MySQLに接続するために
php.ini
を作成php.ini
のモジュール読み込み設定を確認、パスがC直下ではない場合はext
のパスも確認
紆余曲折ありましたが、何とかアップグレードに成功しました。
実は過去にも同環境で2度ほどアップグレードを試みたことがあるのですが、いずれも挫折していました。
今回ようやく成功した形になります……長かった……。
課題
PHPのバージョンのみアップグレードしたので、XAMPP同梱のphpMyadminから警告が出るようになってしまいました。
警告を無視すれば使えはしますが、こちらも要調整と思われます。
参考
PHPのみのアップグレード手順
vcruntime140.dll
関連
- Visual Studio 2019 for Windows および Mac のダウンロード: ダウンロードリンク
- XAMPPでApache起動出来ずにハマった話 – Qiita: エラーメッセージ
- 「MSVCR140.dll/VCRUNTIME140.dllがないため、プログラムが開始できません」と表示された場合 | PHPインストールと初期設定: 手順
- VC++ 再頒布可能パッケージのインストール方法 (VC15-19) | SEECK.JP サポート: 手順2
- 最新のサポートされる Visual C++ のダウンロード
MySQLに接続できない・モジュールが読み込まれていない関連
- 指定されたモジュールが見つからないとか言われる – ぱせらんメモ
- 拡張モジュールのディレクトリを指定 – extension_dir – php.iniの設定 – Windows環境 – PHP入門のカルマ
- PHP – PDO support enabled PDO drivers no value|teratail
エラーメッセージの文字化け関連
- 指定されたモジュールが見つからないとか言われる – ぱせらんメモ
- エンコードマニアックス
SJIS-WIN
を指定した場合に化けた文字列と「指定されたモジュールが見つかりません。」の文字列が合致することを確認