quickstart-create-model.xml 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <!-- EN-Revision: 24259 -->
  4. <sect1 id="learning.quickstart.create-model">
  5. <title>モデルとデータベーステーブルの作成</title>
  6. <para>
  7. 始める前にちょっと考えてみましょう。これらのクラスはどこにあって、それをどのように探すのでしょうか?
  8. わたしたちが作成したデフォルトのプロジェクトでは、一つのオートローダーがインスタンス化されます。
  9. そこへ、他のクラスを探せるよう別のオートローダーを付け加えることができます。
  10. MVC の様々なクラスはふつう一つのツリー -- ここでは <filename>application/</filename> --
  11. に集まっていて、ほとんどの場合には共通のプレフィックスを持っていてほしいものです。
  12. </para>
  13. <para>
  14. <classname>Zend_Controller_Front</classname> は、独立したミニアプリケーション、
  15. すなわち "モジュール" という考え方を採用しています。モジュールは <command>zf</command>
  16. ツールが <filename>application/</filename> 以下に設定するディレクトリ構造を模倣しており、
  17. その中の全てのクラスはモジュール名を共通のプレフィックスとして持っているものと見なされます。
  18. <filename>application/</filename> はそれ自体が一つのモジュール -- "default" または "application"
  19. モジュール -- です。以上を踏まえてこのディレクトリ下にあるリソースのオートロードを設定していきたいと思います。
  20. </para>
  21. <para>
  22. <classname>Zend_Application_Module_Autoloader</classname> は、あるモジュールの様々なリソースを
  23. 適切なディレクトリに対応付けるために必要となる機能を提供し、同時に、名前の付け方の規約も提供します。
  24. このクラスのインスタンスは、デフォルトではブートストラップ・オブジェクトの初期化時に作成され、
  25. アプリケーションのブートストラップでは "Application" というプレフィックスをデフォルトで使用します。
  26. そのため、モデル、フォーム、テーブル・クラスはどれも、プレフィックス "Application_" で始めます。
  27. </para>
  28. <para>
  29. では、ゲストブックを作っていくことにしましょう。一般的には<emphasis>コメント</emphasis>、
  30. <emphasis>タイムスタンプ</emphasis>、それからたまに<emphasis>メールアドレス</emphasis>を持つ単純なリストになります。
  31. それらをデータベースに保存するとしたら、各エントリーのユニークな識別子も欲しいかも知れません。
  32. エントリーを保存したり特定のエントリーを取ってきたり全エントリーを読み出したくなることでしょう。
  33. そうだとすると、簡単なゲストブックモデルの <acronym>API</acronym> はこのようになりそうです。
  34. </para>
  35. <programlisting language="php"><![CDATA[
  36. // application/models/Guestbook.php
  37. class Application_Model_Guestbook
  38. {
  39. protected $_comment;
  40. protected $_created;
  41. protected $_email;
  42. protected $_id;
  43. public function __set($name, $value);
  44. public function __get($name);
  45. public function setComment($text);
  46. public function getComment();
  47. public function setEmail($email);
  48. public function getEmail();
  49. public function setCreated($ts);
  50. public function getCreated();
  51. public function setId($id);
  52. public function getId();
  53. }
  54. class Application_Model_GuestbookMapper
  55. {
  56. public function save(Application_Model_Guestbook $guestbook);
  57. public function find($id);
  58. public function fetchAll();
  59. }
  60. ]]></programlisting>
  61. <para>
  62. <methodname>__get()</methodname> と <methodname>__set()</methodname> は、
  63. 各エントリーのプロパティにアクセスする便利な仕組みと、他のゲッター、セッターのプロキシを提供してくれます。
  64. また、オブジェクト中の許可したプロパティのみアクセス可能にするのにも役立ちます。
  65. </para>
  66. <para>
  67. <methodname>find()</methodname> と <methodname>fetchAll()</methodname> は単一のエントリーや
  68. 全てのエントリーをフェッチする機能を提供し、<methodname>save()</methodname> は
  69. 一つのエントリーをデータストアに保存する面倒を見ます。
  70. </para>
  71. <para>
  72. ここでようやく、データベース設定について考え始めることができます。
  73. </para>
  74. <para>
  75. まず <classname>Db</classname> リソースを初期化する必要があります。
  76. <classname>Layout</classname> リソースと <classname>View</classname> リソースから <classname>Db</classname>
  77. リソースの設定を準備できます。これには <command>zf configure db-adapter</command> コマンドが使えます。
  78. </para>
  79. <programlisting language="shell"><![CDATA[
  80. % zf configure db-adapter \
  81. > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' \
  82. > production
  83. A db configuration for the production has been written to the application config file.
  84. % zf configure db-adapter \
  85. > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-testing.db"' \
  86. > testing
  87. A db configuration for the production has been written to the application config file.
  88. % zf configure db-adapter \
  89. > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-dev.db"' \
  90. > development
  91. A db configuration for the production has been written to the application config file.
  92. ]]></programlisting>
  93. <para>
  94. ここで <filename>application/configs/application.ini</filename> ファイルの相当する部分に
  95. 以下の行が追加されているのが見付かるので、編集します。
  96. </para>
  97. <programlisting language="ini"><![CDATA[
  98. ; application/configs/application.ini
  99. [production]
  100. ; ...
  101. resources.db.adapter = "PDO_SQLITE"
  102. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
  103. [testing : production]
  104. ; ...
  105. resources.db.adapter = "PDO_SQLITE"
  106. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
  107. [development : production]
  108. ; ...
  109. resources.db.adapter = "PDO_SQLITE"
  110. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
  111. ]]></programlisting>
  112. <para>
  113. 設定ファイルが最終的に以下のようになるようにしてください。
  114. </para>
  115. <programlisting language="ini"><![CDATA[
  116. ; application/configs/application.ini
  117. [production]
  118. phpSettings.display_startup_errors = 0
  119. phpSettings.display_errors = 0
  120. bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
  121. bootstrap.class = "Bootstrap"
  122. appnamespace = "Application"
  123. resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
  124. resources.frontController.params.displayExceptions = 0
  125. resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
  126. resources.view[] =
  127. resources.db.adapter = "PDO_SQLITE"
  128. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
  129. [staging : production]
  130. [testing : production]
  131. phpSettings.display_startup_errors = 1
  132. phpSettings.display_errors = 1
  133. resources.db.adapter = "PDO_SQLITE"
  134. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
  135. [development : production]
  136. phpSettings.display_startup_errors = 1
  137. phpSettings.display_errors = 1
  138. resources.db.adapter = "PDO_SQLITE"
  139. resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
  140. ]]></programlisting>
  141. <para>
  142. データベースは <filename>data/db/</filename> に保存されることに注意しましょう。
  143. ディレクトリを作って全ユーザーに書き込み権限を与えます。ユニックスライクなシステムでは、
  144. 次のようにすれば設定できます。
  145. </para>
  146. <programlisting language="shell"><![CDATA[
  147. % mkdir -p data/db; chmod -R a+rwX data
  148. ]]></programlisting>
  149. <para>
  150. Windows では、エクスプローラでディレクトリを作り、
  151. 全ユーザーがそのディレクトリに書き込めるようアクセス権を設定する必要があります。
  152. </para>
  153. <para>
  154. この段階でデータベース接続が行えます。今の例では <filename>application/data/</filename>
  155. ディレクトリ内にある Sqlite データベースへの接続です。では、ゲストブックのエントリーを入れる簡単なテーブルを設計しましょう。
  156. </para>
  157. <programlisting language="sql"><![CDATA[
  158. -- scripts/schema.sqlite.sql
  159. --
  160. -- この SQL からデータベーススキーマをロードする必要があります。
  161. CREATE TABLE guestbook (
  162. id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  163. email VARCHAR(32) NOT NULL DEFAULT 'noemail@test.com',
  164. comment TEXT NULL,
  165. created DATETIME NOT NULL
  166. );
  167. CREATE INDEX "id" ON "guestbook" ("id");
  168. ]]></programlisting>
  169. <para>
  170. それから、素晴らしい仕事ができるように、数行、アプリケーションを面白くするする情報を作りましょう。
  171. </para>
  172. <programlisting language="sql"><![CDATA[
  173. -- scripts/data.sqlite.sql
  174. --
  175. -- 以下の SQL 文でデータベースに生命を吹き込めます。
  176. INSERT INTO guestbook (email, comment, created) VALUES
  177. ('ralph.schindler@zend.com',
  178. 'Hello! Hope you enjoy this sample zf application!',
  179. DATETIME('NOW'));
  180. INSERT INTO guestbook (email, comment, created) VALUES
  181. ('foo@bar.com',
  182. 'Baz baz baz, baz baz Baz baz baz - baz baz baz.',
  183. DATETIME('NOW'));
  184. ]]></programlisting>
  185. <para>
  186. これでスキーマができ、データもいくらか定義できました。それでは一緒にスクリプトを書いてこのデータベースの構築を実行しましょう。
  187. 普通は、プロダクション環境でこういったことは必要ありませんが、このスクリプトがあれば開発者が必要なデータベースを手元で構築して、アプリケーションの作業に全力投球するのを助けてくれるでしょう。
  188. 以下の内容で、<filename>scripts/load.sqlite.php</filename> としてスクリプトを作ってください。
  189. </para>
  190. <programlisting language="php"><![CDATA[
  191. // scripts/load.sqlite.php
  192. /**
  193. * データベースを作成して読み込むスクリプト
  194. */
  195. // アプリケーションパスとオートロードの初期化
  196. defined('APPLICATION_PATH')
  197. || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
  198. set_include_path(implode(PATH_SEPARATOR, array(
  199. APPLICATION_PATH . '/../library',
  200. get_include_path(),
  201. )));
  202. require_once 'Zend/Loader/Autoloader.php';
  203. Zend_Loader_Autoloader::getInstance();
  204. // CLI 用のオプション
  205. $getopt = new Zend_Console_Getopt(array(
  206. 'withdata|w' => 'Load database with sample data',
  207. 'env|e-s' => 'Application environment for which to create database (defaults to development)',
  208. 'help|h' => 'Help -- usage message',
  209. ));
  210. try {
  211. $getopt->parse();
  212. } catch (Zend_Console_Getopt_Exception $e) {
  213. // オプションが不正な場合に使用法を表示
  214. echo $e->getUsageMessage();
  215. return false;
  216. }
  217. // ヘルプが要求された場合に使用法を表示
  218. if ($getopt->getOption('h')) {
  219. echo $getopt->getUsageMessage();
  220. return true;
  221. }
  222. // CLI オプションの有無に応じて値を初期化
  223. $withData = $getopt->getOption('w');
  224. $env = $getopt->getOption('e');
  225. defined('APPLICATION_ENV')
  226. || define('APPLICATION_ENV', (null === $env) ? 'development' : $env);
  227. // Zend_Application の初期化
  228. $application = new Zend_Application(
  229. APPLICATION_ENV,
  230. APPLICATION_PATH . '/configs/application.ini'
  231. );
  232. // DB リソースの初期化と読み込み
  233. $bootstrap = $application->getBootstrap();
  234. $bootstrap->bootstrap('db');
  235. $dbAdapter = $bootstrap->getResource('db');
  236. // やっていることをユーザーに通知
  237. // (実際にここでデータベースを作る)
  238. if ('testing' != APPLICATION_ENV) {
  239. echo 'Writing Database Guestbook in (control-c to cancel): ' . PHP_EOL;
  240. for ($x = 5; $x > 0; $x--) {
  241. echo $x . "\r"; sleep(1);
  242. }
  243. }
  244. // データベースファイルが既にないかチェック
  245. $options = $bootstrap->getOption('resources');
  246. $dbFile = $options['db']['params']['dbname'];
  247. if (file_exists($dbFile)) {
  248. unlink($dbFile);
  249. }
  250. // このブロックでスキーマファイルから読み込んだ実際のステートメントを実行
  251. try {
  252. $schemaSql = file_get_contents(dirname(__FILE__) . '/schema.sqlite.sql');
  253. // use the connection directly to load sql in batches
  254. $dbAdapter->getConnection()->exec($schemaSql);
  255. chmod($dbFile, 0666);
  256. if ('testing' != APPLICATION_ENV) {
  257. echo PHP_EOL;
  258. echo 'Database Created';
  259. echo PHP_EOL;
  260. }
  261. if ($withData) {
  262. $dataSql = file_get_contents(dirname(__FILE__) . '/data.sqlite.sql');
  263. // use the connection directly to load sql in batches
  264. $dbAdapter->getConnection()->exec($dataSql);
  265. if ('testing' != APPLICATION_ENV) {
  266. echo 'Data Loaded.';
  267. echo PHP_EOL;
  268. }
  269. }
  270. } catch (Exception $e) {
  271. echo 'AN ERROR HAS OCCURED:' . PHP_EOL;
  272. echo $e->getMessage() . PHP_EOL;
  273. return false;
  274. }
  275. // 大抵の場合、このスクリプトはコマンドラインから走らせて true を返す
  276. ]]></programlisting>
  277. <para>
  278. このスクリプトを実行しましょう。ターミナルか DOS のコマンドラインから以下を実行してください。
  279. </para>
  280. <programlisting language="shell"><![CDATA[
  281. % php scripts/load.sqlite.php --withdata
  282. ]]></programlisting>
  283. <para>
  284. 以下のような出力を目にすると思います。
  285. </para>
  286. <programlisting language="text"><![CDATA[
  287. path/to/ZendFrameworkQuickstart/scripts$ php load.sqlite.php --withdata
  288. Writing Database Guestbook in (control-c to cancel):
  289. 1
  290. Database Created
  291. Data Loaded.
  292. ]]></programlisting>
  293. <para>
  294. これでゲストブックアプリケーションのためにきちんと動くデータベースとテーブルができました。
  295. 次のステップはアプリケーションのコードを作成することです。
  296. これにはデータソース(ここでは <classname>Zend_Db_Table</classname> を使います)と、
  297. そのデータソースをドメインモデルに繋げる役目のデータマッパーを構築することが含まれます。
  298. 最後に、既存のエントリーの表示と新規エントリーの処理をモデルに結び付けるコントローラーも作ります。
  299. </para>
  300. <para>
  301. ここではデータソースへの接続に<ulink url="http://martinfowler.com/eaaCatalog/tableDataGateway.html">テーブルデータゲートウェイ</ulink> を使います。
  302. <classname>Zend_Db_Table</classname> がこの機能を提供してくれます。
  303. 始めるにあたって <classname>Zend_Db_Table</classname> ベースのクラスを作りましょう。
  304. レイアウトとデータベースアダプタでやった時と同じように、<command>zf</command>
  305. ツールの力を借りることができます。<command>create db-table</command> コマンドを使うのです。
  306. これは最低で 2 つの引数をとります。参照させるクラスと、対応付けるデータベーステーブルの名前です。
  307. </para>
  308. <programlisting language="shell"><![CDATA[
  309. % zf create db-table Guestbook guestbook
  310. Creating a DbTable at application/models/DbTable/Guestbook.php
  311. Updating project profile 'zfproject.xml'
  312. ]]></programlisting>
  313. <para>
  314. ディレクトリツリーを見てみると、新規ディレクトリ <filename>application/models/DbTable/</filename>
  315. が作られてファイル <filename>Guestbook.php</filename> が作られているのが分かります。
  316. ファイルを開くと以下の内容になっています。
  317. </para>
  318. <programlisting language="php"><![CDATA[
  319. // application/models/DbTable/Guestbook.php
  320. /**
  321. * This is the DbTable class for the guestbook table.
  322. */
  323. class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract
  324. {
  325. /** Table name */
  326. protected $_name = 'guestbook';
  327. }
  328. ]]></programlisting>
  329. <para>
  330. クラスのプレフィックス <classname>Application_Model_DbTable</classname> に注目しましょう。
  331. 最初の部分がモジュールのクラスプレフィックス "Application" で、その後にコンポーネント
  332. "Model_DbTable" がきます。後者はモジュールのディレクトリ <filename>models/DbTable/</filename>
  333. に対応付けられています。
  334. </para>
  335. <para>
  336. <classname>Zend_Db_Table</classname> を拡張する際に必要なのはテーブル名と場合により主キーを
  337. ("id" でなければ)与えることだけです。
  338. </para>
  339. <para>
  340. では <ulink url="http://martinfowler.com/eaaCatalog/dataMapper.html">データマッパー</ulink>
  341. を作成しましょう。<emphasis>データマッパー</emphasis> はドメインオブジェクトをデータベースに対応付けます。
  342. ここではモデル <classname>Application_Model_Guestbook</classname> をデータソース
  343. <classname>Application_Model_DbTable_Guestbook</classname> に対応付けることになります。
  344. データマッパーの典型的な <acronym>API</acronym> は次のようになるでしょう。
  345. </para>
  346. <programlisting language="php"><![CDATA[
  347. // application/models/GuestbookMapper.php
  348. class Application_Model_GuestbookMapper
  349. {
  350. public function save($model);
  351. public function find($id, $model);
  352. public function fetchAll();
  353. }
  354. ]]></programlisting>
  355. <para>
  356. こうしたメソッドの他に、テーブルデータゲートウェイを設定してそこからデータを取り出すメソッドを追加します。
  357. クラスの最初の形を作成するのに CLI の <command>zf</command> ツールを使います。
  358. </para>
  359. <programlisting language="shell"><![CDATA[
  360. % zf create model GuestbookMapper
  361. Creating a model at application/models/GuestbookMapper.php
  362. Updating project profile '.zfproject.xml'
  363. ]]></programlisting>
  364. <para>
  365. 次に <filename>application/models/GuestbookMapper.php</filename> にあるクラス
  366. <classname>Application_Model_GuestbookMapper</classname> を編集して下記の通りにします。
  367. </para>
  368. <programlisting language="php"><![CDATA[
  369. // application/models/GuestbookMapper.php
  370. class Application_Model_GuestbookMapper
  371. {
  372. protected $_dbTable;
  373. public function setDbTable($dbTable)
  374. {
  375. if (is_string($dbTable)) {
  376. $dbTable = new $dbTable();
  377. }
  378. if (!$dbTable instanceof Zend_Db_Table_Abstract) {
  379. throw new Exception('Invalid table data gateway provided');
  380. }
  381. $this->_dbTable = $dbTable;
  382. return $this;
  383. }
  384. public function getDbTable()
  385. {
  386. if (null === $this->_dbTable) {
  387. $this->setDbTable('Application_Model_DbTable_Guestbook');
  388. }
  389. return $this->_dbTable;
  390. }
  391. public function save(Application_Model_Guestbook $guestbook)
  392. {
  393. $data = array(
  394. 'email' => $guestbook->getEmail(),
  395. 'comment' => $guestbook->getComment(),
  396. 'created' => date('Y-m-d H:i:s'),
  397. );
  398. if (null === ($id = $guestbook->getId())) {
  399. unset($data['id']);
  400. $this->getDbTable()->insert($data);
  401. } else {
  402. $this->getDbTable()->update($data, array('id = ?' => $id));
  403. }
  404. }
  405. public function find($id, Application_Model_Guestbook $guestbook)
  406. {
  407. $result = $this->getDbTable()->find($id);
  408. if (0 == count($result)) {
  409. return;
  410. }
  411. $row = $result->current();
  412. $guestbook->setId($row->id)
  413. ->setEmail($row->email)
  414. ->setComment($row->comment)
  415. ->setCreated($row->created);
  416. }
  417. public function fetchAll()
  418. {
  419. $resultSet = $this->getDbTable()->fetchAll();
  420. $entries = array();
  421. foreach ($resultSet as $row) {
  422. $entry = new Application_Model_Guestbook();
  423. $entry->setId($row->id)
  424. ->setEmail($row->email)
  425. ->setComment($row->comment)
  426. ->setCreated($row->created);
  427. $entries[] = $entry;
  428. }
  429. return $entries;
  430. }
  431. }
  432. ]]></programlisting>
  433. <para>
  434. これでモデルクラスが作れます。ここでもコマンド <command>zf create model</command> を使います。
  435. </para>
  436. <programlisting language="shell"><![CDATA[
  437. % zf create model Guestbook
  438. Creating a model at application/models/Guestbook.php
  439. Updating project profile '.zfproject.xml'
  440. ]]></programlisting>
  441. <para>
  442. この空の <acronym>PHP</acronym> クラスを修正して、コンストラクタでも <methodname>setOptions()</methodname>
  443. メソッドでも、データの配列からモデルを生成するのを簡単にします。<filename>application/models/Guestbook.php</filename>
  444. 中の最終的なモデルクラスはこのようになるはずです。
  445. </para>
  446. <programlisting language="php"><![CDATA[
  447. // application/models/Guestbook.php
  448. class Application_Model_Guestbook
  449. {
  450. protected $_comment;
  451. protected $_created;
  452. protected $_email;
  453. protected $_id;
  454. public function __construct(array $options = null)
  455. {
  456. if (is_array($options)) {
  457. $this->setOptions($options);
  458. }
  459. }
  460. public function __set($name, $value)
  461. {
  462. $method = 'set' . $name;
  463. if (('mapper' == $name) || !method_exists($this, $method)) {
  464. throw new Exception('Invalid guestbook property');
  465. }
  466. $this->$method($value);
  467. }
  468. public function __get($name)
  469. {
  470. $method = 'get' . $name;
  471. if (('mapper' == $name) || !method_exists($this, $method)) {
  472. throw new Exception('Invalid guestbook property');
  473. }
  474. return $this->$method();
  475. }
  476. public function setOptions(array $options)
  477. {
  478. $methods = get_class_methods($this);
  479. foreach ($options as $key => $value) {
  480. $method = 'set' . ucfirst($key);
  481. if (in_array($method, $methods)) {
  482. $this->$method($value);
  483. }
  484. }
  485. return $this;
  486. }
  487. public function setComment($text)
  488. {
  489. $this->_comment = (string) $text;
  490. return $this;
  491. }
  492. public function getComment()
  493. {
  494. return $this->_comment;
  495. }
  496. public function setEmail($email)
  497. {
  498. $this->_email = (string) $email;
  499. return $this;
  500. }
  501. public function getEmail()
  502. {
  503. return $this->_email;
  504. }
  505. public function setCreated($ts)
  506. {
  507. $this->_created = $ts;
  508. return $this;
  509. }
  510. public function getCreated()
  511. {
  512. return $this->_created;
  513. }
  514. public function setId($id)
  515. {
  516. $this->_id = (int) $id;
  517. return $this;
  518. }
  519. public function getId()
  520. {
  521. return $this->_id;
  522. }
  523. }
  524. ]]></programlisting>
  525. <para>
  526. 最後に、以上の要素を全て一つに繋げます。データベース内の既存のエントリーを一覧表示する
  527. ゲストブック用のコントローラを作りましょう。
  528. </para>
  529. <para>
  530. 新しいコントローラを作るには <command>zf create controller</command> コマンドを使います。
  531. </para>
  532. <programlisting language="shell"><![CDATA[
  533. % zf create controller Guestbook
  534. Creating a controller at
  535. application/controllers/GuestbookController.php
  536. Creating an index action method in controller Guestbook
  537. Creating a view script for the index action method at
  538. application/views/scripts/guestbook/index.phtml
  539. Creating a controller test file at
  540. tests/application/controllers/GuestbookControllerTest.php
  541. Updating project profile '.zfproject.xml'
  542. ]]></programlisting>
  543. <para>
  544. このコマンドによって <filename>application/controllers/GuestbookController.php</filename> の中に
  545. <classname>GuestbookController</classname> が作られ、そこには一つのアクションメソッド
  546. <methodname>indexAction()</methodname> が出来ています。また、このコントローラーの
  547. ビュースクリプト用ディレクトリ <filename>application/views/scripts/guestbook/</filename>
  548. とインデックスアクション用のビュースクリプトも作成されます。
  549. </para>
  550. <para>
  551. ゲスブックの全エントリーを表示する入り口用のページとして "index" アクションを使います。
  552. </para>
  553. <para>
  554. では、基本的なアプリケーションロジックを一息に作ってしまいましょう。<methodname>indexAction()</methodname>
  555. へやって来るとゲストブックの全エントリーを表示します。これは次のようになります。
  556. </para>
  557. <programlisting language="php"><![CDATA[
  558. // application/controllers/GuestbookController.php
  559. class GuestbookController extends Zend_Controller_Action
  560. {
  561. public function indexAction()
  562. {
  563. $guestbook = new Application_Model_GuestbookMapper();
  564. $this->view->entries = $guestbook->fetchAll();
  565. }
  566. }
  567. ]]></programlisting>
  568. <para>
  569. それからもちろんこれに使うビュースクリプトが必要です。
  570. <filename>application/views/scripts/guestbook/index.phtml</filename> を以下のように編集します。
  571. </para>
  572. <programlisting language="php"><![CDATA[
  573. <!-- application/views/scripts/guestbook/index.phtml -->
  574. <p><a href="<?php echo $this->url(
  575. array(
  576. 'controller' => 'guestbook',
  577. 'action' => 'sign'
  578. ),
  579. 'default',
  580. true) ?>">Sign Our Guestbook</a></p>
  581. Guestbook Entries: <br />
  582. <dl>
  583. <?php foreach ($this->entries as $entry): ?>
  584. <dt><?php echo $this->escape($entry->email) ?></dt>
  585. <dd><?php echo $this->escape($entry->comment) ?></dd>
  586. <?php endforeach ?>
  587. </dl>
  588. ]]></programlisting>
  589. <note>
  590. <title>チェックポイント</title>
  591. <para>
  592. ここで "http://localhost/guestbook" にアクセスしてみましょう。
  593. ブラウザには次のように表示されるはずです。
  594. </para>
  595. <para>
  596. <inlinegraphic width="525" scale="100" align="center" valign="middle"
  597. fileref="figures/learning.quickstart.create-model.png" format="PNG" />
  598. </para>
  599. </note>
  600. <note>
  601. <title>データローダースクリプトの使用</title>
  602. <para>
  603. この節で導入したデータローダースクリプト(<filename>scripts/load.sqlite.php</filename>)は
  604. 定義した環境のそれぞれでデータベースを作りサンプルデータを読み込むのに使用できます。
  605. 内部では、多くのコマンドラインスイッチを提供できるようにしてくれる
  606. <classname>Zend_Console_Getopt</classname> を利用しています。"-h" または "--help"
  607. スイッチを渡すと使用可能なオプションを提示します。
  608. </para>
  609. <programlisting language="php"><![CDATA[
  610. Usage: load.sqlite.php [ options ]
  611. --withdata|-w Load database with sample data
  612. --env|-e [ ] Application environment for which to create database
  613. (defaults to development)
  614. --help|-h Help -- usage message]]
  615. ]]></programlisting>
  616. <para>
  617. "-e" スイッチを使うと <constant>APPLICATION_ENV</constant> 定数に使用する値を指定できます。
  618. -- 定義した各環境で順に SQLite データベースを作れるようになるのです。
  619. デプロイ時に、アプリケーション用に選んだ環境で確実にこのスクリプトを走らせるようにしてください。
  620. </para>
  621. </note>
  622. </sect1>