Zend Framework2.0 を試してみる(3)
Zend Framework2.0 を試してみる - Memo
Zend Framework2.0 を試してみる(2) - Memo
の続き。
Create a Model and Database Table
チュートリアルではデータベースアダプターに PDO_Sqite を使うようだ。
まずは設定ファイルにデータベース接続の設定を作る。
zf コマンドで普通に出来た。
$ php bin/zf.php configure db-adapter 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' production A db configuration for the production section has been written to the application config file. $ php bin/zf.php configure db-adapter 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-testing.db"' testing A db configuration for the testing section has been written to the application config file. $ php bin/zf.php configure db-adapter 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-dev.db"' development A db configuration for the development section has been written to the application config file.
guestbook.db, guestbook-testing.db, guestbook-dev.db というファイルを quickstart/data/db/ というディレクトリに格納する。
$ mkdir -p data/db; chmod -R a+rwX data
スキーマとスキーマを読み込んで、テーブルを作るスクリプトを作る。
スキーマのファイルはチュートリアルにあるのをそのまま使う。
とりあえず quickstart/scripts 以下に schema.sqlite.sql, data.sqlite.sql を格納する。
スキーマを読み込みテーブルを作る PHP スクリプト は zf2 では作られていない。
$ diff -u load.sqlite.php.orig load.sqlite.php --- load.sqlite.php.orig 2010-07-25 00:54:23.000000000 +0900 +++ load.sqlite.php 2010-07-25 00:55:56.000000000 +0900 @@ -13,10 +13,10 @@ ))); require_once 'Zend/Loader/Autoloader.php'; -Zend_Loader_Autoloader::getInstance(); +Zend\Loader\Autoloader::getInstance(); // Define some CLI options -$getopt = new Zend_Console_Getopt(array( +$getopt = new Zend\Console\Getopt(array( 'withdata|w' => 'Load database with sample data', 'env|e-s' => 'Application environment for which to create database (defaults to development)', 'help|h' => 'Help -- usage message', @@ -43,7 +43,7 @@ || define('APPLICATION_ENV', (null === $env) ? 'development' : $env); // Initialize Zend_Application -$application = new Zend_Application( +$application = new Zend\Application\Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' );
単純に名前空間を変えただけ。
実行してみる。
$ php scripts/load.sqlite.php --withdata FAILED TO FIND Zend\Db\Adapter\PDO_SQLITE Fatal error: Class 'Zend\Db\Adapter\PDO_SQLITE' not found in /var/php/zf2/zf/library/Zend/Db/Db.php on line 261
PDO_SQLITE ってのが存在しないみたい。
application/configs/application.ini に設定した resources.db.adapter = "PDO_SQLITE" だと読み込めない。
resources.db.adapter = "PDO\SQLITE" という風に全て変更する。
再度実行する。
$ php scripts/load.sqlite.php --withdata Writing Database Guestbook in (control-c to cancel): 1 Database Created Data Loaded.
今度は無事に作れた。
続いて Model を作る。
チュートリアルでは Table Data Gateway パターンと Data Mapper パターンを使う。
Models/DbTable/Gustbook.php には Zend\Db\Table\AbstractTable クラスを継承して作る。
Models/GuestbookMapper.php にマッパーを作る。
$ php bin/zf.php create db-table Guestbook guestbook Creating a DbTable at /var/php/zf2/zf/quickstart/application/models/DbTable/Guestbook.php Updating project profile '/var/php/zf2/zf/quickstart/.zfproject.xml' $ php bin/zf.php create model GuestbookMapper Creating a model at /var/php/zf2/zf/quickstart/application/models/GuestbookMapper.php Updating project profile '/var/php/zf2/zf/quickstart/.zfproject.xml' $ php bin/zf.php create model Guestbook Creating a model at /var/php/zf2/zf/quickstart/application/models/Guestbook.php Updating project profile '/var/php/zf2/zf/quickstart/.zfproject.xml'
んで、チュートリアルのコードを diff ったもの。
$ diff -u Guestbook.php.orig Guestbook.php --- Guestbook.php.orig 2010-07-25 01:59:05.000000000 +0900 +++ Guestbook.php 2010-07-25 22:35:36.000000000 +0900 @@ -1,10 +1,7 @@ <?php +namespace Application\Model\DbTable; -class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract +class Guestbook extends \Zend\Db\Table\AbstractTable { - protected $_name = 'guestbook'; - - } $ diff GuestbookMapper.php.orig GuestbookMapper.php 2c2,6 < class Application_Model_GuestbookMapper --- > namespace Application\Model; > use Application\Model\Guestbook, > Application\Model\DbTable\Guestbook as GustbookTable; > > class GuestbookMapper 11,12c15,17 < if (!$dbTable instanceof Zend_Db_Table_Abstract) { < throw new Exception('Invalid table data gateway provided'); --- > > if (!$dbTable instanceof \Zend\Db\Table\AbstractTable) { > throw new \Exception('Invalid table data gateway provided'); 21c26 < $this->setDbTable('Application_Model_DbTable_Guestbook'); --- > $this->setDbTable('Application\Model\DbTable\Guestbook'); 26c31 < public function save(Application_Model_Guestbook $guestbook) --- > public function save(Guestbook $guestbook) 42c47 < public function find($id, Application_Model_Guestbook $guestbook) --- > public function find($id, Guestbook $guestbook) 60c65 < $entry = new Application_Model_Guestbook(); --- > $entry = new Guestbook(); $ diff -u Guestbook.php.orig Guestbook.php --- Guestbook.php.orig 2010-07-26 01:46:39.000000000 +0900 +++ Guestbook.php 2010-07-25 03:20:10.000000000 +0900 @@ -1,6 +1,7 @@ <?php +namespace Application\Model; -class Application_Model_Guestbook +class Guestbook { protected $_comment; protected $_created;
名前空間とかを変えただけ。
続いてコントローラを作る。
$ php bin/zf.php create controller Guestbook Fatal error: Cannot use Zend\Tool\Project\Profile as Profile because the name is already in use in /var/php/zf2/zf/library/Zend/Tool/Project/Provider/Test.php on line 27
んー。library/Zend/Tool/Project/Provider/Test.php を変更。
Profile ってのがダメみたいなので、同階層にある他のクラスと同じように ProjectProfile にする。
$ diff -u Test.php.orig Test.php --- Test.php.orig 2010-07-25 02:40:43.000000000 +0900 +++ Test.php 2010-07-25 02:52:25.000000000 +0900 @@ -24,7 +24,7 @@ * @namespace */ namespace Zend\Tool\Project\Provider; -use Zend\Tool\Project\Profile; +use Zend\Tool\Project\Profile as ProjectProfile; /** * @uses \Zend\Tool\Project\Provider\AbstractProvider @@ -45,7 +45,7 @@ * @param \Zend\Tool\Project\Profile $profile * @return bool */ - public static function isTestingEnabled(Profile $profile) + public static function isTestingEnabled(ProjectProfile $profile) { $profileSearchParams = array('testsDirectory'); $testsDirectory = $profile->search($profileSearchParams); @@ -62,7 +62,7 @@ * @param string $moduleName * @return \Zend\Tool\Project\Profile\Resource */ - public static function createApplicationResource(Profile $profile, $controllerName, $actionName, $moduleName = null) + public static function createApplicationResource(ProjectProfile $profile, $controllerName, $actionName, $moduleName = null) { if (!is_string($controllerName)) { throw new Exception('Zend_Tool_Project_Provider_View::createApplicationResource() expects \"controllerName\" is the name of a controller resource to create.'); @@ -99,7 +99,7 @@ * @param string $libraryClassName * @return \Zend\Tool\Project\Profile\Resource */ - public static function createLibraryResource(Profile $profile, $libraryClassName) + public static function createLibraryResource(ProjectProfile $profile, $libraryClassName) { $testLibraryDirectoryResource = $profile->search(array('TestsDirectory', 'TestLibraryDirectory'));
再度実行。
$ php bin/zf.php create controller Guestbook Warning: include_once(Zend/Tool/Framework/Client/HelpSystem.php): failed to open stream: No such file or directory in /var/php/zf2/zf/library/Zend/Loader.php on line 151
むー。
library/Zend/Tool/Framework/Client/Console.php の HelpSystem(); の名前空間がおかしい。
$ diff -u Console.php.orig Console.php --- Console.php.orig 2010-07-22 22:28:59.000000000 +0900 +++ Console.php 2010-07-25 03:08:10.000000000 +0900 @@ -185,18 +185,18 @@ { $response = $this->_registry->getResponse(); - $response->addContentDecorator(new ResponseDecorator\AlignCenter()); - $response->addContentDecorator(new ResponseDecorator\Indention()); - $response->addContentDecorator(new ResponseDecorator\Blockize()); + $response->addContentDecorator(new Console\ResponseDecorator\AlignCenter()); + $response->addContentDecorator(new Console\ResponseDecorator\Indention()); + $response->addContentDecorator(new Console\ResponseDecorator\Blockize()); if (function_exists('posix_isatty')) { - $response->addContentDecorator(new ResponseDecorator\Colorizer()); + $response->addContentDecorator(new Console\ResponseDecorator\Colorizer()); } $response->addContentDecorator(new \Zend\Tool\Framework\Client\Response\ContentDecorator\Separator()) ->setDefaultDecoratorOptions(array('separator' => true)); - $optParser = new ArgumentParser(); + $optParser = new Console\ArgumentParser(); $optParser->setArguments($_SERVER['argv']) ->setRegistry($this->_registry) ->parse(); @@ -214,7 +214,7 @@ $response = $this->_registry->getResponse(); if ($response->isException()) { - $helpSystem = new HelpSystem(); + $helpSystem = new Console\HelpSystem(); $helpSystem->setRegistry($this->_registry) ->respondWithErrorMessage($response->getException()->getMessage(), $response->getException()) ->respondWithSpecialtyAndParamHelp(
.zfproject.xml にゴミが出来てる可能性があるので、Controller に関する所で Guestbook となっているのを削除し再度実行。
$ php bin/zf.php create controller Guestbook Creating a controller at /var/php/zf2/zf/quickstart/application/controllers/GuestbookController.php Creating an index action method in controller Guestbook Creating a view script for the index action method at /var/php/zf2/zf/quickstart/application/views/scripts/guestbook/index.phtml Creating a controller test file at /var/php/zf2/zf/quickstart/tests/application/controllers/GuestbookControllerTest.php Updating project profile '/var/php/zf2/zf/quickstart/.zfproject.xml'
なぜかコントローラクラスだけ zf2 でジェネレートされた。
indexAction() に以下を追加する。
<?php public function indexAction() { $guestbook = new Application\Model\GuestbookMapper(); $this->view->entries = $guestbook->fetchAll(); }
views/scripts/guestbook/index.phtml にも以下を追加。
<p><a href="<?php echo $this->url( array( 'controller' => 'guestbook', 'action' => 'sign' ), 'default', true) ?>">Sign Our Guestbook</a></p> Guestbook Entries: <br /> <dl> <?php foreach ($this->entries as $entry): ?> <dt><?php echo $this->escape($entry->email) ?></dt> <dd><?php echo $this->escape($entry->comment) ?></dd> <?php endforeach ?> </dl>
ブラウザで http://localhost/guestbook にアクセスしたら、登録した初期データが表示される。