Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

pythonistaのためのphp用の開発サーバ

phpで開発する時の開発用サーバとかよくわからなかった。
未だにapacheとか云々するのもなんだかなあと思うんだけど。
まあpythonistaならwphp使うよねって話。

wphp
http://pythonpaste.org/wphp/

こいつはwsgiインターフェイスphpfastcgiで動かしてくれる。

from wphp import PHPApp
from wsgiref.simple_server import make_server

my_php_app = PHPApp('/path/to/php-files/',
                    php_options={'magic_quote_gpc': 'Off'} )

httpd = make_server('', 8000, my_php_app)
httpd.serve_forever()

とまあこれでOK。
でもデフォルトでは基本的に拡張子がphpでファイルが実在する場合しか動いてくれないので注意。

CakePHPの場合

とりあえずcakephpを動かすためには有無を言わさずindex.phpを渡すようにする。
なのでやっつけでwphpの呼び出し部をいじる。
(ゴリゴリに書いてあるので拡張しようがない)

wphp/__init__.py
    def __call__(self, environ, start_response):
        if 'REQUEST_URI' not in environ:
            # PHP likes to have this variable
            environ['REQUEST_URI'] = (
                environ.get('SCRIPT_NAME', '')
                + environ.get('PATH_INFO', ''))
            if environ.get('QUERY_STRING'):
                environ['REQUEST_URI'] += '?'+environ['QUERY_STRING']
        if self.child_pid is None:
            if environ['wsgi.multiprocess']:
                environ['wsgi.errors'].write(
                    "wphp doesn't support multiprocess apps very well yet")
            self.create_child()
        path_info = environ.get('PATH_INFO', '').lstrip('/')
        full_path = os.path.join(self.base_dir, path_info)
        if (os.path.isdir(full_path)
            and not environ.get('PATH_INFO', '').endswith('/')):
            # We need to do a redirect
            new_url = construct_url(environ) + '/'
            redir = HTTPMovedPermanently(headers=[('location', new_url)])
            return redir.wsgi_application(environ, start_response)
        #script_filename, path_info = self.find_script(self.base_dir, path_info)
        #if script_filename is None:
        #    exc = HTTPNotFound()
        #    return exc(environ, start_response)
        
        #script_name = posixpath.join(environ.get('SCRIPT_NAME', ''), script_filename)
        #script_filename = posixpath.join(self.base_dir, script_filename)
        #environ['SCRIPT_NAME'] = script_name
        #environ['SCRIPT_FILENAME'] = os.path.join(self.base_dir, script_filename)

        environ['SCRIPT_NAME'] = 'index.php'
        environ['SCRIPT_FILENAME'] = os.path.join(self.base_dir, 'index.php')
        environ['PATH_INFO'] = path_info
    
        #ext = posixpath.splitext(script_filename)[1]
        #if ext != '.php':
        #    if self.logger:
        #        self.logger.debug(
        #            'Found static file at %s',
        #            script_filename)
        #    app = fileapp.FileApp(script_filename)
        #    return app(environ, start_response)
        #if self.logger:
        #    self.logger.debug(
        #        'Found script at %s', script_filename)
        if (environ['REQUEST_METHOD'] == 'POST'
            and not environ.get('CONTENT_TYPE')):
            environ['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
        app_iter = self.fcgi_app(environ, start_response)
        return app_iter

これでCakePHPは動く。
開発用の鯖があると便利な点は読み込めるPHPファイルを限定できるという点。
apache以下に複数のPHPのプロジェクトがあるとURLが云々とかありそうなので)

とまあ書いてみたけどwsgirefだとcloseを呼んでないのでfastcgiのプロセスが残るんだよな。。。
なのでPasteDeploy経由でやった方がいいですよ、動くかわからんけどね。