なんと創業4年弱ではじめてphp案件をいただきました。現在がんばり中です。

で、phpっていうとapacheと一緒に動いてるイメージしかなかったんですが、PHP-FPMというのがあって、FastCGIのサーバーとして動かすことができるらしい、と言うのを昨日知りました。

ということは! Plack::App::FCGIDispatcherでplackを前にかますことができるのではないだろうか!!

やってみましたよ。

use strict;
use warnings;
use Plack::Builder;
use Plack::App::FCGIDispatcher;
use Plack::Request;

my $app = Plack::App::FCGIDispatcher->new({
    socket => '/home/danjou/php/var/run/fpm.socket'
});

my $dir = '/home/danjou/work/ec-cube/eccube-2.11.1/html';

builder {
    enable 'ReverseProxy';
    enable 'Static',
        path => qr{\.(css|js|jpg|gif|png)$}, root => $dir;
    enable sub {
        my $app = shift;
        sub {
            my $env = shift;
            my $req = Plack::Request->new($env);
            my $uri = $req->uri;
            if ($uri->path =~ m{/$}) {
                $uri->path($uri->path . 'index.php');
                $env->{PATH_INFO} = $uri->path;
                $env->{REQUEST_URI} = $uri->path_query;
            }
            $env->{SCRIPT_FILENAME} = $dir.$uri->path;

            my $res = eval{ $app->($env) };
            if (my $error = $@) {
                return [502, ['Content-Type' => 'text/plain'], [$error]];
            }
            return $res;
        };
    };
    $app;
};

# vim: ft=perl :

スマートではないですが、「DirectoryIndex index.php」がしたかったのが「if ($uri->path =~ m{/$})」のあたりです。

ほんで最初は$_SERVER[‘PHP_SELF’]ってなんや!$env->{PHP_SELF} = $uri->pathとかするんか!とか思ってたんですが、$env->{PATH_INFO}をいじっておけば良かったようなので、そのようにしてあります。

んで、たまに謎の

Can't call method "print" on an undefined value at /home/danjou/perl5/perlbrew/perls/perl-5.12.1/lib/site_perl/5.12.1/Plack/Util.pm line 162.

と言うエラーが出て、なんやろう?と思ったら

REQUEST_TIME_OUT at /home/danjou/perl5/perlbrew/perls/perl-5.12.1/lib/site_perl/5.12.1/FCGI/Client/Connection.pm line 25

でした。なので、timeoutを渡せるといいな、とおもいました。

で、plackを前に挟むと何がいいかというと、perlでテストが書ける、Middlewareを使える、辺りかなと思います。ぼくはリクエストとレスポンスをダンプするMiddlewareをかまして様子を見るのに使おうと思っています。