ZendFrameworkで作る『イマドキ』のWebアプリケーション

第5回Zend Framework 1.8と新しいZend_Tool

ZendFramework 1.8が2009/4/30にリリースされました。この連載ではZend Framework 1.7を利用してきましたが、今後は1.8を利用します。Zend Framework 1.8は基本的に下位互換です。

それでは1.8の主な新機能を簡単に紹介します。

Zend Framework 1.8の新機能

Zend Framework 1.8の主な新機能は次の通りです。

Zend_Tool
プロジェクト、コントローラ、アクション等のスケルトンコードの自動生成
Zend_Application
アプリケーションのフレームワーク
Zend_Navigator
ナビゲーション
Zend_CodeGenerator
コード生成のフレームワーク
Zend_Serivce_Amazon_Ec2
Amazon EC2サービス用のインターフェース
Zend_Service_Amazon_S3
Amazon S3サービス用のインターフェース

このほかにも多数の機能が追加され、200以上のバグが修正されています。

この連載では1.7に付属していたZend_Toolプレビュー版のコマンドであるzfスクリプトを利用してきました。プレビュー版ということもあり、本来使えるはずのコード生成機能が使えませんでしたが、正式リリースとなりすべての機能が利用できるようになりました。

図1 zfコマンドのヘルプ画面
図1 zfコマンドのヘルプ画面

1.7と1.8のzfコマンドの違い

1.8のzfコマンドでプロジェクトを作成した場合、UNITテスト用のディレクトリが作成されたり、基本的なエラー処理を行うエラーコントローラやビューが用意されるようになりました。プロジェクトを生成して自動的に作成されるデフォルトページも、テキストだけだったものがグラフィックを含んだページに更新されています。

図2 デフォルトのページ
図2 デフォルトのページ

最も重要な違いは、プロジェクトを生成した時にコピーされていたZend Frameworkライブラリがコピーされなくなったことです。シンボリックリンク等を使って、Zend Frameworkのファイルを保存しているZendディレクトリにアクセスできるようにしなければなりません。

Zend Framework 1.8のインストール

ZendFrameworkのダウンロードページから1.8をダウンロードします。

執筆時点(2009/5/9)ではプレビューリリース版のダウンロードページと記載されていますが、ダウンロードできるファイルは正式版のZend Framework 1.8.0です。

今回から/wwwディレクトリにZendFrameworkを展開することにします。

[framework@localhost $ cd /www
[framework@localhost www]$ tar zxvf ZendFramework-1.8.0.tar.gz

新しいzfコマンドの使い方

新しいzfコマンドは従来通りシンボリックリンクでパスが通っている場所へリンクを作ってからも利用できますが、マニュアルとチュートリアルには直接スクリプトを実行するように記載されています。好みの方法で起動するとよいでしょう。

[framework@localhost www]$ ZendFramework-1.8.0/bin/zf.sh --help

を実行するとヘルプが参照できます。

プロジェクトの作成

  • zf create project path

でプロジェクトが作成できます。プロジェクトを作成してみましょう。

[framework@localhost www]$ ZendFramework-1.8.0/bin/zf.sh create project test

プロジェクトファイルの中身は

[framework@localhost www]$ ls -R test
test:
application  library  public  tests

test/application:
Bootstrap.php  configs  controllers  models  views

test/application/configs:
application.ini

test/application/controllers:
ErrorController.php  IndexController.php

test/application/models:

test/application/views:
helpers  scripts

test/application/views/helpers:

test/application/views/scripts:
error  index

test/application/views/scripts/error:
error.phtml

test/application/views/scripts/index:
index.phtml

test/library:

test/public:
index.php

test/tests:
application  library  phpunit.xml

test/tests/application:
bootstrap.php

test/tests/library:
bootstrap.php

となっており、testディレクトリにテスト用コードが配置され、Zend Frameworkライブラリファイルがコピーされていないことがわかります。Linuxなどのシステムではシンボリックリンクが便利なのでリンクを作ることにします。Windowsの場合はコピーしてしまうほうが簡単です。

Zend Frameworkのファイルへのアクセス

ライブラリファイルがコピーされていないので、プロジェクト削除直後はまだスケルトンを実行できません。

[framework@localhost www]$ cd test/library/
[framework@localhost library]$ ls
[framework@localhost library]$ ln -s ../../ZendFramework-1.8.0/library/Zend
[framework@localhost library]$ ls
Zend

後はWebサーバがアクセスできるように/www/defaultのシンボリックリンクを更新します。

[framework@localhost www]$ rm default
[framework@localhost www]$ ln -sf test default

これで新しく作成したZend Frameworkアプリケーションのスケルトンにアクセスできるようになります。

エラーページの問題

エラー処理のページも用意されていますが、このページには問題があります。

<?php
<?php echo

のショートカットである

<?
<?=

が利用されているため、php.ini設定によっては正しく表示できません。

図3 ショートタグ問題
図3 ショートタグ問題

アプリケーション起動時に必ず読み込まれるbootstrap.phpでストリームラッパーを使用し、読み込み時に⁠<?⁠⁠、⁠<?=⁠⁠<?php⁠⁠、⁠<?php echo⁠に書き換える仕組みがZend Frameworkによって提供されていますが、この機能はかなりのオーバーヘッドが必要なためあまりお勧めできません。エディタの置換機能を使って書き換えてしまったほうがよいです。

図4 正常なエラーページ
図4 正常なエラーページ

新しいページ(コントローラ、アクション、ビュー)の作成

Controller
zf create controller name index-action-included[=1]
View
zf create view controller-name action-name-or-simple-name
Action
zf create action name controller-name[=index] view-included[=1]

zfコマンドは上記の書式でコントローラ、アクション、ビューの作成が可能です。

  • http://localhost/foo/bar/

としてアクセスできる、barアクションを実行するfooコントローラのページを作成してみましょう。

[framework@localhost default]$ zf create controller  foo
Creating a controller at /www/test/application/controllers/FooController.php
Creating an index action method in controller foo
Creating a view script for the index action method at /www/test/application/views/scripts/foo/index.phtml
Creating a controller test file at /www/test/tests/application/controllers/FooControllerTest.php
Updating project profile '/www/test/.zfproject.xml'

indexコントローラも一緒に作成されたことが分かります。まずはindexコントローラにアクセスして動作を確かめてみましょう。

図5 http://localhost/foo
図5 http://localhost/foo

テキストだけのページですが、コントローラもビューも用意されているのでエラー無くページが表示されます。

今度はbarアクションを追加してみましょう。

[framework@localhost default]$ zf create action bar foo
Creating an action named bar inside controller at /www/test/application/controllers/FooController.php
Updating project profile '/www/test/.zfproject.xml'
Creating a view script for the bar action method at /www/test/application/views/scripts/foo/bar.phtml
図6 http://localhost/foo/bar
図6 http://localhost/foo/bar

必要なアクションがFooController.phpに追加され、ビューのbar.phtmlファイルが作成されたことが分かります。

FooController.phpとbar.phtmlの中身を見てみましょう。

FooController.php
<?php

class FooController extends Zend_Controller_Action
{

    public function init()
    {
        /* Initialize action controller here */
    }

    public function indexAction()
    {
        // action body
    }

    public function barAction()
    {
        // action body
    }


}
bar.phtml
<br /><br /><center>View script for controller <b>foo</b> and script/action name <b>bar</b></center>

この程度なら自分でコピーして作成してもよさそうですが、今後zfコマンドはさまざまな拡張が行われるようです。

zfコマンドで作成したプロジェクトの管理ファイル

コントローラとビューを作成する際に.zfproject.xmlファイルが更新されていることが分かります。これはプロジェクトの状態を保存するとともにプロジェクト内にどのようなコントローラ、アクション、ビューがあるか管理するファイルです。

.zfproject.xml
<?xml version="1.0"?>
<projectProfile>
  <projectDirectory>
    <projectProfileFile/>
    <applicationDirectory>
      <apisDirectory enabled="false"/>
      <configsDirectory>
        <applicationConfigFile type="ini"/>
      </configsDirectory>
      <controllersDirectory>
        <controllerFile controllerName="index">
          <actionMethod actionName="index"/>
        </controllerFile>
        <controllerFile controllerName="error"/>
        <controllerFile controllerName="foo">
          <actionMethod actionName="index"/>
          <actionMethod actionName="bar"/>
        </controllerFile>
      </controllersDirectory>
      <layoutsDirectory enabled="false"/>
      <modelsDirectory/>
      <modulesDirectory enabled="false"/>
      <viewsDirectory>
        <viewScriptsDirectory>
          <viewControllerScriptsDirectory forControllerName="index">
            <viewScriptFile forActionName="index"/>
          </viewControllerScriptsDirectory>
          <viewControllerScriptsDirectory forControllerName="error">
            <viewScriptFile forActionName="error"/>
          </viewControllerScriptsDirectory>
          <viewControllerScriptsDirectory forControllerName="foo">
            <viewScriptFile forActionName="index"/>
          </viewControllerScriptsDirectory>
(以下省略)

このファイルを見ると、レイアウトやモジュールディレクトリなど多くの設定項目があることが分かります。今後、zfコマンドがどのように拡張されていくのか予想できます。

今のところzfコマンドは単純なスケルトン作成コマンドでしかありませんが、Zend Frameworkを利用するならzfコマンドでプロジェクト、コントローラ、アクション、ビューを作成するほうがよいでしょう。

guestbookアプリの動作

Zend Framework 1.8.0は上位互換ですが、ゲストブックのように簡単なアプリケーションでもアップグレードには注意が必要です。

図7 仕様変更の予告エラー
図7 仕様変更の予告エラー

index.php/bootstrap.phpの入れ替え

1.8のzfコマンドが生成するpublic/index.phpとapplication/bootstrap.phpのコードが変わり、クラス自動ロードの方法が変更されるのでエラーが発生しています。

1.7のindex.php
<?php
// @see application/bootstrap.php
$bootstrap = true;
require '../application/bootstrap.php';

// $frontController is created in your boostrap file. Now we'll dispatch it, which dispatches your application.
$frontController->dispatch();
1.7のbootstrap.php
<?php
// ** Check to see if the environment is already setup **
if (isset($bootstrap) && $bootstrap) {
    // Enable all errors so we'll know when something goes wrong.
    error_reporting(E_ALL | E_STRICT);
    ini_set('display_startup_errors', 1);
    ini_set('display_errors', 1);

    // Add our  directory to the include path so that PHP can find the Zend Framework classes.
    // you may wish to add other paths here, or keep system paths: set_include_path('../library' . PATH_SEPARATOR . get_include_path()
    set_include_path('../library');

    // Set up autoload.
    // This is a nifty trick that allows ZF to load classes automatically so that you don't have to litter your
    // code with 'include' or 'require' statements.
    require_once "Zend/Loader.php";
    Zend_Loader::registerAutoload();
}

// ** Get the front controller **
// The Zend_Front_Controller class implements the Singleton pattern, which is a design pattern used to ensure
// there is only one instance of Zend_Front_Controller created on each request.
$frontController = Zend_Controller_Front::getInstance();

// Point the front controller to your action controller directory.
$frontController->setControllerDirectory('../application/controllers');

// Set the current environment
// Set a variable in the front controller indicating the current environment --
// commonly one of development, staging, testing, production, but wholly
// dependent on your organization and site's needs.
$frontController->setParam('env', 'development');

1.8のコードでは初期化の多くがindex.phpに移動され、bootstrap.phpには空のクラスだけが定義されています。BoostrapクラスはZend Applicationから自動的に読み込まれるようになっています。また、アプリケーションの実行環境は環境変数から取得されるように変更されています。

1.8のindex.php
<?php

// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

/** Zend_Application */
require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
            ->run();
1.8のbootstrap.php
<?php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{


}

Zend Framework 1.8でguestbook2アプリを動作させるためには、新しいzfコマンドで生成したpublic/index.php、application/bootstrap.phpをコピーし、library/Zendを削除し、新しいZend Frameworkのライブラリにアクセスできるようにするだけです。

動作環境の設定

1.7のzfコマンドで生成したプロジェクトでは、動作環境がbootstrap.phpにハードコードされていましたが、1.8のzfコマンドではAPPLICATION_ENV環境変数で動作環境を設定できるようになりました。デフォルトの動作環境はproductionに設定されているので、エラーページに詳細なエラー情報が表示されなくなります。

Apacheの場合、環境変数はmod_envモジュールのsetEnvディレクティブで設定できます。httpd.confの最後に[1]

SetEnv APPLICATION_ENV development

を追加してWebサーバを再起動します[2]⁠。

これでエラーページに詳細なエラー情報は表示されるべきなのですが、viewオブジェクトのenvに動作環境が設定されていません。APPLICATION_ENV定数はindex.phpで定義済みなのでviewオブジェクトの$this->envの代わりにAPPLICATION_ENV定数を利用すると詳細なエラーが表示できるようになります[3]⁠。

図8 必要な修正を終えた後のエラーページ
図8 必要な修正を終えた後のエラーページ

まとめ

目立った機能追加などはありませんが、zfコマンドの仕様はプレビュー版と随分異なります。変更された部分はよい変更だと言えると思います。public/index.phpに基本設定を持たせ、Zend Applicationからアプリケーションがブートストラップコードを読み込む変更、APPLICATION_ENV環境変数から動作環境を設定できるように変更されたのでプロダクションサーバへのデプロイメントも容易になりました。

今後は新しいzfコマンドを使ってアプリケーションを構築していきます。

おすすめ記事

記事・ニュース一覧