Edited at

zend-expressive-skeletonをGoogleAppEngine/PHPにインストール

More than 3 years have passed since last update.

Zend公式のPSR-7対応マイクロフレームワーク「zend-expressive」を使ってみようと思い、

Google App Engine にインストールしたので、備忘メモです。

https://github.com/zendframework/zend-expressive

インストールした zend-expressive のバージョンは、1.0.0 です。

--2016.06.10追記 start--


この記事の内容を踏まえて、

別記事「zend-expressive-skeletonをGoogleAppEngine/PHP向けにカスタマイズ

で、簡単にインストールできるカスタマイズ版スケルトンを用意しました。


--2016.06.10追記 end--


skeleton をインストール

動作確認しやすいように、スケルトンをインストールします。

テンプレートエンジンを「Plates」にした以外は、デフォルトのままです。

$ composer create-project zendframework/zend-expressive-skeleton <project dir>

Minimal skeleton? (no default middleware, templates, or assets; configuration only)
[y] Yes (minimal)
[n] No (full; recommended)
Make your selection (No):

Which router do you want to use?
[1] Aura.Router
[2] FastRoute
[3] Zend Router
Make your selection or type a composer package name and version (FastRoute):

Which container do you want to use for dependency injection?
[1] Aura.Di
[2] Pimple
[3] Zend ServiceManager
Make your selection or type a composer package name and version (Zend ServiceManager):

Which template engine do you want to use?
[1] Plates
[2] Twig
[3] Zend View installs Zend ServiceManager
[n] None of the above
Make your selection or type a composer package name and version (n): 1

Which error handler do you want to use during development?
[1] Whoops
[n] None of the above
Make your selection or type a composer package name and version (Whoops):


project dir の直下に app.yaml を追加

Google App Engine に必要な設定ファイルです。

とりあえず、サンプル画面を表示できる程度の設定にしました。

module: default

version: 1
runtime: php55
api_version: 1

handlers:
- url: /favicon.ico
static_files: public/favicon.ico
upload: public/favicon.ico

- url: /zf-logo.png
static_files: public/zf-logo.png
upload: public/zf-logo.png

- url: /.*
script: public/index.php


ローカル環境で動作確認(失敗)

参考: https://cloud.google.com/appengine/docs/php/quickstart#test_the_application

恒例のSDKで動作確認してみます。

$ dev_appserver.py <project dir>

ブラウザで、localhost:8080 にアクセスしてみると。

すわ fatal error です。

Catchable fatal error: Argument 1 passed to Zend\ServiceManager\Config::__construct() must be of the type array, null given, called in /Users/shuhei/Documents/src/googleAppEngine/phpzend/config/container.php on line 11 and defined in /Users/shuhei/Documents/src/googleAppEngine/phpzend/vendor/zendframework/zend-servicemanager/src/Config.php on line 65

config/autoload 配下の定義ファイルを glob することができずに困っているようです。


Load configuration for Google App Engine

定義ファイルの読み込みは、config/config.php で行っていますが、問題点は以下の2点です。


  • glob()関数を使っている

  • 定義ファイルの内容をキャッシュする際の出力先がファイル (file_put_contents)

Google App Engine向けの読み込み処理を作成しました。


  • glob()関数を opendir()/readdir()関数に変更

  • キャッシュ出力先を、ファイルからMemcacheへ変更

以下の内容を

config/config-gae.php

として、配置します。


config/config-gae.php

<?php

use Zend\Stdlib\ArrayUtils;

/**
* Configuration files are loaded in a specific order. First ``global.php``, then ``*.global.php``.
* then ``local.php`` and finally ``*.local.php``. This way local settings overwrite global settings.
*
* The configuration can be cached. This can be done by setting ``config_cache_enabled`` to ``true``.
*
* Obviously, if you use closures in your config you can't cache it.
*/

$cachedConfigKey = 'cache_app_config';

$mc = new Memcached();

// Try to load the cached config
if(!($config = $mc->get($cachedConfigKey))) {
if ($mc->getResultCode() == Memcached::RES_NOTFOUND) {
$config = [];
}
$confdir = __DIR__ . '/autoload';
if ($handle = opendir($confdir)) {
$pattern = '/(global|local)\.php$/';
$files = [];
while (false !== ($file = readdir($handle))) {
if (preg_match($pattern, $file) === 1) {
$fn = implode('.', array_reverse(explode('.', $file)));
$files[] = $fn;
}
}
asort($files);
foreach($files as $file) {
$fn = implode('.', array_reverse(explode('.', $file)));
$config = ArrayUtils::merge($config, include $confdir.'/'.$fn);
}
closedir($handle);
}

// Cache config if enabled
if (isset($config['config_cache_enabled']) && $config['config_cache_enabled'] === true) {
$mc->set($cachedConfigKey, $config);
}
}

// Return an ArrayObject so we can inject the config as a service in Aura.Di
// and still use array checks like ``is_array``.
return new ArrayObject($config, ArrayObject::ARRAY_AS_PROPS);


呼び出し元の

config/container.php

を編集します。


config/container.php

// Load configuration

//$config = require __DIR__ . '/config.php';
$config = require __DIR__ . '/config-gae.php';


ローカル環境で動作確認(成功)

SDKのWebサーバが自動的にリロードしてくれるので、

ブラウザをリロードすれば、正常に表示されるはずです。

Zend Expressive

app_config.php の最後に記載しているように、

エラー画面テンプレートも用意されているので、404 Not Foundの画面も表示できます。


デプロイ

参考: https://cloud.google.com/appengine/docs/php/quickstart#deploy_your_app

https://console.developers.google.com/

で、プロジェクトを作成して、該当のプロジェクトIDに向けてデプロイしましょう。

$ appcfg.py -A YOUR_PROJECT_ID update app.yaml

http://(YOUR_PROJECT_ID).appspot.com/

今後、開発を進める上でどのような問題が出るか分かりませんが、ひとまず第一歩、完了です。