経緯
PHP でプログラムを書いていますが、 npm パッケージも使っているし Browsersync を使いたい。
ついでに PHP だけではなくて .htaccess も併せて挙動を確認したい、という場面に遭遇したのでメモ。
XAMPP + Browsersync であれば以下のような形で proxy とPHPの実行エンジンを指定すれば PHP プログラムの挙動も併せて確認できます。
browsersync.js
const gulp = require('gulp');
const browserSync = require('browser-sync');
const connect = require('gulp-connect-php');
const dotenv = require('dotenv').config();
const browsersync = () => {
connect.server({
port: 8001,
base: dir.dist.html,
bin: process.env.PHP_BIN,
ini: process.env.PHP_INI
}, () =>{
browserSync({
proxy: process.env.PHP_PROXY
});
});
};
.env
PHP_BIN=C:/xampp/php/php.exe
PHP_INI=C:/xampp/php/php.ini
PHP_PROXY=localhost:8001
ここで、今回試したい PHP アプリケーションのディレクトリ階層は以下の通りとなります。
root/
├ src/ //PHPアプリケーション本体
├ vendor/
├ root/ //Dispatcher や静的リソースの置き場所
│ └ index.php //Dispatcher
├ .env //環境変数
├ .htaccess
├ composer.json
└ readme.md
前提として、
- サブディレクトリに展開することも視野に入れた構成
./root/index.php
がアプリケーションの起点プログラム.htaccess
には「http://localhost/PATH/TO/APP/
へアクセスした際、http://localhost/PATH/TO/APP/root/index.php
にリダイレクトして応答させる」設定が既述されている- cssやjs、その他静的リソースファイルは除く
という構成とします。
このとき、冒頭のコードだと gulp-connect-php
から PHP の実行エンジンを直接指定しているので .htaccess
が動作していないのだろう、と思ったため別の方法として以下のスレッドに当たりました。
今回はこのスレッドに倣って http-proxy
(node-http-proxy
)を使用した方法について取り扱います。
備考
ただし、この記事を書く直前に gulp-connect-php
を使用した別の方法を試したところ普通に動いたので、上述の想定は誤りで、実際は .htaccess
の RewriteBase
の指定と Browsersync でアクセスするパスが不一致のためにエラーを起こしていただけのようです。
そのため、この記事で書いた方法は最終的には没になりました……が、後学のために書き留めておきます。
検証
上述のスレッドの書き方を真似て gulp-connect-php
の代わりに http-proxy
をローカルインストールし、以下のように Browsersync のタスクを書き換えます。
browsersync.js
const gulp = require('gulp');
const browserSync = require('browser-sync');
const httpProxy = require('http-proxy');
const dotenv = require('dotenv').config();
const browsersync = () => {
let rootDir = '';
for (let i = 0; i < process.env.ROOT_PATH.split('/').length; i++) {
rootDir += '../';
}
const proxy = httpProxy.createProxyServer({});
browserSync({
server: {
baseDir: rootDir
},
startPath: process.env.ROOT_PATH,
middleware: function (req, res, next) {
proxy.web(req, res, { target: 'http://localhost' });
}
});
};
.env
ROOT_PATH=/PATH/TO/APP/
.env
にはXAMPPのルートからプロジェクトへのパスを既述しておくものとします。
.htaccess
の挙動のため、 http://localhost:3000/
のルートではなく、http://localhost:3000/PATH/TO/APP/
の形でアクセスしたいので、 .env
のパラメータを使って以下のように指定します。
- XAMPP のドキュメントルートである
htdocs
ディレクトリへ遡る相対パスを Browsersync のserver
オプションのbaseDir
として指定 - 逆に
htdocs
からプロジェクトのルートディレクトリまでのパス(.env
の辺りそのもの)をstartPath
に指定
これで意図した通りに PHP アプリケーションにアクセスできることを確認できました。
ただし、一点だけ気になることが。
この方法で http
は確かにアクセスできましたが、折角なので(オレオレ証明書とはいえ) https
での検証もしたいと考えました。
そこで、以下のように書き換えてみました。
browsersync.js
const gulp = require('gulp');
const browserSync = require('browser-sync');
const httpProxy = require('http-proxy');
const dotenv = require('dotenv').config();
const browsersync = () => {
let rootDir = '';
for (let i = 0; i < process.env.ROOT_PATH.split('/').length; i++) {
rootDir += '../';
}
const proxy = httpProxy.createProxyServer({
ssl: {
key: `${process.env.XAMPP_PATH}${process.env.KEY_FILE}`,
cert: `${process.env.XAMPP_PATH}${process.env.CERT_FILE}`
},
target: {
protocol: 'https:',
host: 'localhost',
port: 443
},
secure: true
});
browserSync({
server: {
baseDir: rootDir
},
startPath: process.env.ROOT_PATH,
middleware: function (req, res, next) {
proxy.web(req, res, { target: 'http://localhost' });
}
});
};
.env
XAMPP_PATH=C:/xampp/
CERT_FILE=apache/conf/ssl.crt/server.crt
KEY_FILE=apache/conf/ssl.key/server.key
ROOT_PATH=/PATH/TO/APP/
変更したのは
httpProxy.createProxyServer
時にオプションでhttps
アクセスを強制- SSL証明書のパスを指定
の2箇所。ただし、これで走らせてみると怒られてしまいました。その対処については別記事で。