- path/to/ZendFrameworkQuickstart/scripts$ php load.sqlite.php --withdata
- Writing Database Guestbook in (control-c to cancel):
- 1
- Database Created
- Data Loaded.
Programmer's Reference Guide
| Create A Layout |
モデルとデータベーステーブルの作成
始める前にちょっと考えてみましょう。これらのクラスはどこにあって、それをどのように探すのでしょうか? わたしたちが作成したデフォルトのプロジェクトでは、一つのオートローダーがインスタンス化されます。 そこへ、他のクラスを探せるよう別のオートローダーを付け加えることができます。 MVC の様々なクラスはふつう一つのツリー -- ここでは application/ -- に集まっていて、ほとんどの場合には共通のプレフィックスを持っていてほしいものです。
Zend_Controller_Front は、独立したミニアプリケーション、 すなわち "モジュール" という考え方を採用しています。モジュールは zf ツールが application/ 以下に設定するディレクトリ構造を模倣しており、 その中の全てのクラスはモジュール名を共通のプレフィックスとして持っているものと見なされます。 application/ はそれ自体が一つのモジュール -- "default" または "application" モジュール -- です。以上を踏まえてこのディレクトリ下にあるリソースのオートロードを設定していきたいと思います。
Zend_Application_Module_Autoloader は、あるモジュールの様々なリソースを 適切なディレクトリに対応付けるために必要となる機能を提供し、同時に、名前の付け方の規約も提供します。 このクラスのインスタンスは、デフォルトではブートストラップ・オブジェクトの初期化時に作成され、 アプリケーションのブートストラップでは "Application" というプレフィックスをデフォルトで使用します。 そのため、モデル、フォーム、テーブル・クラスはどれも、プレフィックス "Application_" で始めます。
では、ゲストブックを作っていくことにしましょう。一般的にはコメント、 タイムスタンプ、それからたまにメールアドレスを持つ単純なリストになります。 それらをデータベースに保存するとしたら、各エントリーのユニークな識別子も欲しいかも知れません。 エントリーを保存したり特定のエントリーを取ってきたり全エントリーを読み出したくなることでしょう。 そうだとすると、簡単なゲストブックモデルの API はこのようになりそうです。
- // application/models/Guestbook.php
- class Application_Model_Guestbook
- {
- protected $_comment;
- protected $_created;
- protected $_email;
- protected $_id;
- public function __set($name, $value);
- public function __get($name);
- public function setComment($text);
- public function getComment();
- public function setEmail($email);
- public function getEmail();
- public function setCreated($ts);
- public function getCreated();
- public function setId($id);
- public function getId();
- }
- class Application_Model_GuestbookMapper
- {
- public function save(Application_Model_Guestbook $guestbook);
- public function find($id);
- public function fetchAll();
- }
__get() と __set() は、 各エントリーのプロパティにアクセスする便利な仕組みと、他のゲッター、セッターのプロキシを提供してくれます。 また、オブジェクト中の許可したプロパティのみアクセス可能にするのにも役立ちます。
find() と fetchAll() は単一のエントリーや 全てのエントリーをフェッチする機能を提供し、 save() は 一つのエントリーをデータストアに保存する面倒を見ます。
ここでようやく、データベース設定について考え始めることができます。
まず Db リソースを初期化する必要があります。 Layout リソースと View リソースから Db リソースの設定を準備できます。これには zf configure db-adapter コマンドが使えます。
- % zf configure db-adapter \
- > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' \
- > production
- A db configuration for the production has been written to the application config file.
- % zf configure db-adapter \
- > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-testing.db"' \
- > testing
- A db configuration for the production has been written to the application config file.
- % zf configure db-adapter \
- > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-dev.db"' \
- > development
- A db configuration for the production has been written to the application config file.
ここで application/configs/application.ini ファイルの相当する部分に 以下の行が追加されているのが見付かるので、編集します。
- ; application/configs/application.ini
- [production]
- ; ...
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
- [testing : production]
- ; ...
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
- [development : production]
- ; ...
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
設定ファイルが最終的に以下のようになるようにしてください。
- ; application/configs/application.ini
- [production]
- phpSettings.display_startup_errors = 0
- phpSettings.display_errors = 0
- bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
- bootstrap.class = "Bootstrap"
- appnamespace = "Application"
- resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
- resources.frontController.params.displayExceptions = 0
- resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
- resources.view[] =
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
- [staging : production]
- [testing : production]
- phpSettings.display_startup_errors = 1
- phpSettings.display_errors = 1
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
- [development : production]
- phpSettings.display_startup_errors = 1
- phpSettings.display_errors = 1
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
データベースは data/db/ に保存されることに注意しましょう。 ディレクトリを作って全ユーザーに書き込み権限を与えます。ユニックスライクなシステムでは、 次のようにすれば設定できます。
- % mkdir -p data/db; chmod -R a+rwX data
Windows では、エクスプローラでディレクトリを作り、 全ユーザーがそのディレクトリに書き込めるようアクセス権を設定する必要があります。
この段階でデータベース接続が行えます。今の例では application/data/ ディレクトリ内にある Sqlite データベースへの接続です。では、ゲストブックのエントリーを入れる簡単なテーブルを設計しましょう。
- -- scripts/schema.sqlite.sql
- --
- -- この SQL からデータベーススキーマをロードする必要があります。
- CREATE TABLE guestbook (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- email VARCHAR(32) NOT NULL DEFAULT 'noemail@test.com',
- comment TEXT NULL,
- created DATETIME NOT NULL
- );
- CREATE INDEX "id" ON "guestbook" ("id");
それから、素晴らしい仕事ができるように、数行、アプリケーションを面白くするする情報を作りましょう。
- -- scripts/data.sqlite.sql
- --
- -- 以下の SQL 文でデータベースに生命を吹き込めます。
- INSERT INTO guestbook (email, comment, created) VALUES
- ('ralph.schindler@zend.com',
- 'Hello! Hope you enjoy this sample zf application!',
- DATETIME('NOW'));
- INSERT INTO guestbook (email, comment, created) VALUES
- ('foo@bar.com',
- 'Baz baz baz, baz baz Baz baz baz - baz baz baz.',
- DATETIME('NOW'));
これでスキーマができ、データもいくらか定義できました。それでは一緒にスクリプトを書いてこのデータベースの構築を実行しましょう。 普通は、プロダクション環境でこういったことは必要ありませんが、このスクリプトがあれば開発者が必要なデータベースを手元で構築して、アプリケーションの作業に全力投球するのを助けてくれるでしょう。 以下の内容で、scripts/load.sqlite.php としてスクリプトを作ってください。
- // scripts/load.sqlite.php
- /**
- * データベースを作成して読み込むスクリプト
- */
- // アプリケーションパスとオートロードの初期化
- APPLICATION_PATH . '/../library',
- )));
- require_once 'Zend/Loader/Autoloader.php';
- Zend_Loader_Autoloader::getInstance();
- // CLI 用のオプション
- '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',
- ));
- try {
- $getopt->parse();
- } catch (Zend_Console_Getopt_Exception $e) {
- // オプションが不正な場合に使用法を表示
- return false;
- }
- // ヘルプが要求された場合に使用法を表示
- if ($getopt->getOption('h')) {
- return true;
- }
- // CLI オプションの有無に応じて値を初期化
- $withData = $getopt->getOption('w');
- $env = $getopt->getOption('e');
- // Zend_Application の初期化
- $application = new Zend_Application(
- APPLICATION_ENV,
- APPLICATION_PATH . '/configs/application.ini'
- );
- // DB リソースの初期化と読み込み
- $bootstrap = $application->getBootstrap();
- $bootstrap->bootstrap('db');
- $dbAdapter = $bootstrap->getResource('db');
- // やっていることをユーザーに通知
- // (実際にここでデータベースを作る)
- if ('testing' != APPLICATION_ENV) {
- echo 'Writing Database Guestbook in (control-c to cancel): ' . PHP_EOL;
- for ($x = 5; $x > 0; $x--) {
- }
- }
- // データベースファイルが既にないかチェック
- $options = $bootstrap->getOption('resources');
- $dbFile = $options['db']['params']['dbname'];
- }
- // このブロックでスキーマファイルから読み込んだ実際のステートメントを実行
- try {
- // use the connection directly to load sql in batches
- $dbAdapter->getConnection()->exec($schemaSql);
- if ('testing' != APPLICATION_ENV) {
- echo PHP_EOL;
- echo 'Database Created';
- echo PHP_EOL;
- }
- if ($withData) {
- // use the connection directly to load sql in batches
- $dbAdapter->getConnection()->exec($dataSql);
- if ('testing' != APPLICATION_ENV) {
- echo 'Data Loaded.';
- echo PHP_EOL;
- }
- }
- } catch (Exception $e) {
- echo 'AN ERROR HAS OCCURED:' . PHP_EOL;
- return false;
- }
- // 大抵の場合、このスクリプトはコマンドラインから走らせて true を返す
このスクリプトを実行しましょう。ターミナルか DOS のコマンドラインから以下を実行してください。
- % php scripts/load.sqlite.php --withdata
以下のような出力を目にすると思います。
これでゲストブックアプリケーションのためにきちんと動くデータベースとテーブルができました。 次のステップはアプリケーションのコードを作成することです。 これにはデータソース(ここでは Zend_Db_Table を使います)と、 そのデータソースをドメインモデルに繋げる役目のデータマッパーを構築することが含まれます。 最後に、既存のエントリーの表示と新規エントリーの処理をモデルに結び付けるコントローラーも作ります。
ここではデータソースへの接続に» テーブルデータゲートウェイ を使います。 Zend_Db_Table がこの機能を提供してくれます。 始めるにあたって Zend_Db_Table ベースのクラスを作りましょう。 レイアウトとデータベースアダプタでやった時と同じように、zf ツールの力を借りることができます。create db-table コマンドを使うのです。 これは最低で 2 つの引数をとります。参照させるクラスと、対応付けるデータベーステーブルの名前です。
- % zf create db-table Guestbook guestbook
- Creating a DbTable at application/models/DbTable/Guestbook.php
- Updating project profile 'zfproject.xml'
ディレクトリツリーを見てみると、新規ディレクトリ application/models/DbTable/ が作られてファイル Guestbook.php が作られているのが分かります。 ファイルを開くと以下の内容になっています。
- // application/models/DbTable/Guestbook.php
- /**
- * This is the DbTable class for the guestbook table.
- */
- class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract
- {
- /** Table name */
- protected $_name = 'guestbook';
- }
クラスのプレフィックス Application_Model_DbTable に注目しましょう。 最初の部分がモジュールのクラスプレフィックス "Application" で、その後にコンポーネント "Model_DbTable" がきます。後者はモジュールのディレクトリ models/DbTable/ に対応付けられています。
Zend_Db_Table を拡張する際に必要なのはテーブル名と場合により主キーを ("id" でなければ)与えることだけです。
では » データマッパー を作成しましょう。データマッパー はドメインオブジェクトをデータベースに対応付けます。 ここではモデル Application_Model_Guestbook をデータソース Application_Model_DbTable_Guestbook に対応付けることになります。 データマッパーの典型的な API は次のようになるでしょう。
- // application/models/GuestbookMapper.php
- class Application_Model_GuestbookMapper
- {
- public function save($model);
- public function find($id, $model);
- public function fetchAll();
- }
こうしたメソッドの他に、テーブルデータゲートウェイを設定してそこからデータを取り出すメソッドを追加します。 クラスの最初の形を作成するのに CLI の zf ツールを使います。
- % zf create model GuestbookMapper
- Creating a model at application/models/GuestbookMapper.php
- Updating project profile '.zfproject.xml'
次に application/models/GuestbookMapper.php にあるクラス Application_Model_GuestbookMapper を編集して下記の通りにします。
- // application/models/GuestbookMapper.php
- class Application_Model_GuestbookMapper
- {
- protected $_dbTable;
- public function setDbTable($dbTable)
- {
- $dbTable = new $dbTable();
- }
- if (!$dbTable instanceof Zend_Db_Table_Abstract) {
- throw new Exception('Invalid table data gateway provided');
- }
- $this->_dbTable = $dbTable;
- return $this;
- }
- public function getDbTable()
- {
- if (null === $this->_dbTable) {
- $this->setDbTable('Application_Model_DbTable_Guestbook');
- }
- return $this->_dbTable;
- }
- public function save(Application_Model_Guestbook $guestbook)
- {
- 'email' => $guestbook->getEmail(),
- 'comment' => $guestbook->getComment(),
- );
- if (null === ($id = $guestbook->getId())) {
- $this->getDbTable()->insert($data);
- } else {
- }
- }
- public function find($id, Application_Model_Guestbook $guestbook)
- {
- $result = $this->getDbTable()->find($id);
- return;
- }
- $row = $result->current();
- $guestbook->setId($row->id)
- ->setEmail($row->email)
- ->setComment($row->comment)
- ->setCreated($row->created);
- }
- public function fetchAll()
- {
- $resultSet = $this->getDbTable()->fetchAll();
- foreach ($resultSet as $row) {
- $entry = new Application_Model_Guestbook();
- $entry->setId($row->id)
- ->setEmail($row->email)
- ->setComment($row->comment)
- ->setCreated($row->created);
- $entries[] = $entry;
- }
- return $entries;
- }
- }
これでモデルクラスが作れます。ここでもコマンド zf create model を使います。
- % zf create model Guestbook
- Creating a model at application/models/Guestbook.php
- Updating project profile '.zfproject.xml'
この空の PHP クラスを修正して、コンストラクタでも setOptions() メソッドでも、データの配列からモデルを生成するのを簡単にします。application/models/Guestbook.php 中の最終的なモデルクラスはこのようになるはずです。
- // application/models/Guestbook.php
- class Application_Model_Guestbook
- {
- protected $_comment;
- protected $_created;
- protected $_email;
- protected $_id;
- {
- $this->setOptions($options);
- }
- }
- public function __set($name, $value)
- {
- $method = 'set' . $name;
- throw new Exception('Invalid guestbook property');
- }
- $this->$method($value);
- }
- public function __get($name)
- {
- $method = 'get' . $name;
- throw new Exception('Invalid guestbook property');
- }
- return $this->$method();
- }
- {
- foreach ($options as $key => $value) {
- $this->$method($value);
- }
- }
- return $this;
- }
- public function setComment($text)
- {
- $this->_comment = (string) $text;
- return $this;
- }
- public function getComment()
- {
- return $this->_comment;
- }
- public function setEmail($email)
- {
- $this->_email = (string) $email;
- return $this;
- }
- public function getEmail()
- {
- return $this->_email;
- }
- public function setCreated($ts)
- {
- $this->_created = $ts;
- return $this;
- }
- public function getCreated()
- {
- return $this->_created;
- }
- public function setId($id)
- {
- $this->_id = (int) $id;
- return $this;
- }
- public function getId()
- {
- return $this->_id;
- }
- }
最後に、以上の要素を全て一つに繋げます。データベース内の既存のエントリーを一覧表示する ゲストブック用のコントローラを作りましょう。
新しいコントローラを作るには zf create controller コマンドを使います。
- % zf create controller Guestbook
- Creating a controller at
- application/controllers/GuestbookController.php
- Creating an index action method in controller Guestbook
- Creating a view script for the index action method at
- application/views/scripts/guestbook/index.phtml
- Creating a controller test file at
- tests/application/controllers/GuestbookControllerTest.php
- Updating project profile '.zfproject.xml'
このコマンドによって application/controllers/GuestbookController.php の中に GuestbookController が作られ、そこには一つのアクションメソッド indexAction() が出来ています。また、このコントローラーの ビュースクリプト用ディレクトリ application/views/scripts/guestbook/ とインデックスアクション用のビュースクリプトも作成されます。
ゲスブックの全エントリーを表示する入り口用のページとして "index" アクションを使います。
では、基本的なアプリケーションロジックを一息に作ってしまいましょう。 indexAction() へやって来るとゲストブックの全エントリーを表示します。これは次のようになります。
- // application/controllers/GuestbookController.php
- class GuestbookController extends Zend_Controller_Action
- {
- public function indexAction()
- {
- $guestbook = new Application_Model_GuestbookMapper();
- $this->view->entries = $guestbook->fetchAll();
- }
- }
それからもちろんこれに使うビュースクリプトが必要です。 application/views/scripts/guestbook/index.phtml を以下のように編集します。
- <!-- application/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): ?>
- <?php endforeach ?>
- </dl>
注意: チェックポイント
ここで "http://localhost/guestbook" にアクセスしてみましょう。 ブラウザには次のように表示されるはずです。
注意: データローダースクリプトの使用
この節で導入したデータローダースクリプト(scripts/load.sqlite.php)は 定義した環境のそれぞれでデータベースを作りサンプルデータを読み込むのに使用できます。 内部では、多くのコマンドラインスイッチを提供できるようにしてくれる Zend_Console_Getopt を利用しています。"-h" または "--help" スイッチを渡すと使用可能なオプションを提示します。
"-e" スイッチを使うと APPLICATION_ENV 定数に使用する値を指定できます。 -- 定義した各環境で順に SQLite データベースを作れるようになるのです。 デプロイ時に、アプリケーション用に選んだ環境で確実にこのスクリプトを走らせるようにしてください。
Usage: load.sqlite.php [ options ] --withdata|-w Load database with sample data --env|-e [ ] Application environment for which to create database (defaults to development) --help|-h Help -- usage message]]
| Create A Layout |
Add A Comment
Please do not report issues via comments; use the ZF Issue Tracker.
If you have a JIRA/Crowd account, we suggest you login first before commenting.


Comments
Executing the command as:
zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH \"/../data/db/guestbook.db\"" -s production
zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH \"/../data/db/guestbook-testing.db\"" -s testing
works, but writes
resources.db.params.dbname = "APPLICATION_PATH /../data/db/guestbook.db"
to the configuration, which ofcourse should be
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
Also, trying to configure the development section php raises a notice and does not configure anything (even though it said it did)
PHP Notice: Undefined offset: 28 in C:\Program Files (x86)\Zend\ZendServer\share\ZendFramework\library\Zend\Tool\Project\Provider\DbAdapter.php on line 182
So if you're finding problems with this, for now just manually add the lines to your application.ini
Fatal error: Class 'Application_Model_GuestbookMapper' not found in path\to\quickstart\application\controllers\GuestbookController.php on line 13
After some time of searching the web I found a solution. Just add this to your Bootstrap.php, at the end of the _initDoctype function:
$loader = new Zend_Loader_Autoloader_Resource (array (
'basePath' => APPLICATION_PATH,
'namespace' => 'Application',
));
$loader -> addResourceType ( 'model', 'models', 'Model');
To make it work I had to add the <?php and ?> tags to the beginning and end of the script like so below:
<pre>
if (null === ($id = $guestbook->getId())) {
unset($data['id']); //<--- this should be unset($data[$id]);
$this->getDbTable()->insert($data);
} else {
$this->getDbTable()->update($data, array('id = ?' => $id));
}
</pre>
In a regular php installation the pdo_sqlite is not enable. Make sure this is set in your php.ini file.
Second and in case you get this following error when you run the Guestbook:
SQLSTATE[HY000] [14] unable to open database file
For some reason the DB folder and files need to be inside the /public/ folder which isn't mentioned as far as I can see.
Reverse the quotation marks
Hence this:
'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"'
should be this
"adapter=PDO_SQLITE&dbname=APPLICATION_PATH '/../data/db/guestbook.db'"
zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH '/../data/db/guestbook.db'" -s productionzf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH '/../data/db/guestbook-testing.db'" -s testing
zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH '/../data/db/guestbook-dev.db'" -s development
Also, the data folder should go in the same directory as application directory is, not inside the application directory.
you're wrong about the fact that db folder needs to be in /public/ folder & you're wrong about the fact it's not mentioned.
i invite you to look better :)
anyway, i'm on mac os and have no problem.
for people didn't see that php tags where missing maybe you have to pay more attention what you're doing and not just copy/paste what you see :) the load file is a php script ;)
@tchaOo°
you're wrong about the fact that db folder needs to be in /public/ folder & you're wrong about the fact it's not mentioned.
i invite you to look better :)
anyway, i'm on mac os and have no problem.
for people didn't see that php tags where missing maybe you have to pay more attention what you're doing and not just copy/paste what you see :) the load file is a php script ;)
@tchaOo°
Fatal error: Class 'Application_Model_Guestbook' not found in...
I've found the following solution:
// Add this method to your Bootstrap class
protected function _initAutoload()
{
$loader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Application',
'basePath' => APPLICATION_PATH
));
return $loader;
}
Is anyone could explain the way how apache server will proceed request http://zendtest.local/guestbook?
I have problem, my server show OK for http://zendtest.local, http://zendtest.local/guestbook bring me:
The requested URL /guestbook was not found on this server.
I have been playing with parameters of httpd.conf, but nothing good...
The main thing I do not understand how server should know that such request actiolly should be shown index of view of guestbook?
Thank you in advance.
to use mysql instead of sqlite i found this somewhere to add to application.ini
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "localhost"
resources.db.params.username = "mysqlusername"
resources.db.params.password = "mysqlpassword"
resources.db.params.dbname = "dbname"
I just added this to each production, development and testing sections.
so I skipped the whole create db script and just executed the sql in navicat.
my question is do we need to run elements of that load.sqlite.sql even for a existing mysql db to make the connection work?
I created all the model, view mapper etc.... Got to the end and now get a 404 error saying it cant even find guestbook
This fixed the problem.
"to use mysql instead of sqlite i found this somewhere to add to application.ini"
You did right, it should work, it works for me.
You don´t need to run load.sqlite.sql at all.
Check every other step in case you missed something. Don´t forget to name your database and tables correctly and to grant all privileges to yourself. Check in your apache settings if rewrite_module is enabled, otherwise you'll get 404 errors in all actions other than IndexAction.
Why do people write tutorials as if you are supposed to know what they are talking about?
After all, we came to learn, not guess!
Why do people write tutorials as if you are supposed to know what they are talking about?
After all, we came to learn, not guess!
.htaccess
RewriteEngine OnRewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
in your /path/to/quickstart/public/
it worked on my pc.
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "localhost"
resources.db.params.username = "mysqlusername"
resources.db.params.password = "mysqlpassword"
resources.db.params.dbname = "dbname"
It works:)
Controller:
function searchAction(){
//mostrar o form de pesquisa
}
function viewAction(){
//pega os dados passados e faz a pesquisa no bando dados
$resultado = model->getSearch($nome, $cidade);
$this->view->resultado = $resultado;
}
Model:
function getSearch($nome, $cidade){
??????
return $result;
}
zf configure db-adapter 'adapter=Pdo_Mysql&host=localhost&username=name&password=pass&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' production
zf configure db-adapter 'adapter=Pdo_Mysql&host=localhost&username=name&password=pass&dbname=APPLICATION_PATH "/../data/db/guestbook-testing.db"' test
zf configure db-adapter 'adapter=Pdo_Mysql&host=localhost&username=name&password=pass&dbname=APPLICATION_PATH "/../data/db/guestbook-dev.db"' development
Hope this helps someone else not get as confused as I was.
1. Note that the database(s) will be stored in data/db/. Create those directories, and make them world-writeable. On unix-like systems, you can do that as...
Instead of making these directories world-writeable, use the web server processes user (defined in the User and Group directive in Apache as daemon or www-data) for the directory's user and group, as they will be the PHP process effective user and group. Try the following:
$ pwd
/usr/local/apache/htdocs/example/application
$ sudo chown daemon.daemon data/db
2. In the Application_Model_Guestbook class __get() and __set() magic methods defines that getters and setters might be defines as getproperty() instead of getProperty. If you use getPropertyName and setProperty flavor, change the first line in the magic methods to:
$method = 'get' . ucfirst($name)
and
$method = 'set' . ucfirst($name)
I had trouble adapting this to Microsoft SQL Server. I figured it out eventually.
Here is what you do:
1. Make sure MSSQL works normally with a simple php file.
2. Now to use it with Zend, have the application.ini file look like this:
resources.db.adapter = "sqlsrv"
resources.db.params.host = "***.***.***.***"
resources.db.params.dbname = "Database"
resources.db.params.username = "*******"
resources.db.params.password = "*******"
It should be this simple (hopefully). But also note that youll probably have to create the database and stuff on your own, this is mainly for the important part (i.e. connection to the database for use with other parts of the tutorial).
note: I am on windows server 2008 using IIS7 and Sql Server 2008
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "localhost"
resources.db.params.username = "mysqlusername"
resources.db.params.password = "mysqlpassword"
resources.db.params.dbname = "dbname"
The problem not addressed here is: how do I access data across more then one database? I need a sort of multiadapter for a JOIN that includes a clause like:
db1.table1.id = db2.table1.id
zf configure db-adapter \
Once that is entered you will notice the ">" on the left, that matches the ">" in this tutorial...just keep copying and pasting till the next ">" and you'll be great!
If anyone is unsure of where to put the DB (php and sql) files, you must make a "scripts" folder in your root (quickstart) folder.
Name the files without "scripts/" in front and let the terminal take over
$entry->setOptions($row->toArray());
This also would eliminate the need to modify the find() and fetchAll() methods if the table structure changes during development. And had it not been for the created field that the save() method sets to the current datetime, one could implement a toArray() method in the model and use it to initialize $data in the save() method, which would eliminate the need to modify any part of the mapper if the table structure changes. Plus, the same mapper code could then be used for all models in the application. Or would any of that be considered in any way bad practice?
Another suggestion I have is to expand the if condition in the save() method such that the insert occurs if $id is null or 0. This would make life easier when implementing an editAction() in the controller.
Youssef Eldakar
Bibliotheca Alexandrina
CREATE TABLE guestbook (
id int(11) NOT NULL AUTO_INCREMENT,
email varchar(32) NOT NULL DEFAULT 'noemail@test.com',
`comment` text,
created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
)
INSERT INTO guestbook (email, comment, created) VALUES
('ralph.schindler@zend.com',
'Hello! Hope you enjoy this sample zf application!',
NOW()),
('foo@bar.com',
'Baz baz baz, baz baz Baz baz baz - baz baz baz.',
NOW());
CREATE TABLE guestbook (
id int(11) NOT NULL AUTO_INCREMENT,
email varchar(32) NOT NULL DEFAULT 'noemail@test.com',
`comment` text,
created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
)
INSERT INTO guestbook (email, comment, created) VALUES
('ralph.schindler@zend.com',
'Hello! Hope you enjoy this sample zf application!',
NOW()),
('foo@bar.com',
'Baz baz baz, baz baz Baz baz baz - baz baz baz.',
NOW());
First, the chapter opens with the idea of specifying a prefix ("Application_") to the class files generated by the zf tool, but there's a procedure to cause that to happen, and someone forgot to write it up (?). So far my application.ini is similar to the one shown after the db adapter configuration, but when I create the database table class its class name is Model_DbTable_Guestbook instead of Application_Model_DbTable_Guestbook. It's not too much work to add the prefix manually, but clearly it's not the way things are supposed to work at this point.
Also, the code for the GuestbookMapper class is repeated, it appears first in application/model/Guestbook.php, and then again on its own. I'm pretty sure it should only show up in its own file.
Regarding the "Fatal error: Class 'Application_Model_Guestbook' not found in..." problem, I encountered it too. Plamena marinova's solution above is the answer, not Joao Portelo's, because it makes clear what you are doing - initialising the autoloader, not the document type, although well done Joao for tracking down the required lines of code.
Comment 2
I also had a problem with the class Model_Db_Table_Guestbook not being found. When I used,
zf create db-table Guestbook guestbook
the class that was created was Model_DbTable_Guestbook and not Application_Model_DbTable_Guestbook, with the result that the autoloader was unable to find it.
Changing all references to the class to include the Application_ prefix made it work.
I am using Zend Framework 1.10.7. Is this a bug? If not, is there a different fix?
$this->view->layout()->disableLayout();
Youssef Eldakar
Bibliotheca Alexandrina
@Finau Kaufusi on: 2010-02-20 16:50:38
The "unset($data['id'])" is correct. If it should be $id it would be null so that the code "unset($data[null])" wouldn't make sense.
Sidtj
Sumaré, SP, Brazil
Application_Model_Page::__set, __get and setOptions are particularly brilliant and instructional. They are generic enough to abstract out into their own Model Parent class and use with any tables that require field based access. Is there a recommended way to do this that fits tightly into the Zend architecture?
My first inclination is to the create a ZendExtensions directory next to the Zend directory in the library, then subpath based on the Zend namespace to keep it all organized (ie: ZendExtensions/Model/ModelExtension.php).
Does this parallel directory structure make sense? Should I contribute ideas like this to the community instead?
Thanks again,
David
Application_Model_Page::__set, __get and setOptions are particularly brilliant and instructional. They are generic enough to abstract out into their own Model Parent class and use with any tables that require field based access. Is there a recommended way to do this that fits tightly into the Zend architecture?
My first inclination is to the create a ZendExtensions directory next to the Zend directory in the library, then subpath based on the Zend namespace to keep it all organized (ie: ZendExtensions/Model/ModelExtension.php).
Does this parallel directory structure make sense? Should I contribute ideas like this to the community instead?
Thanks again,
David
zf configure db-adapter "adapter=PDO_MYSQL&dbname=crowdom&host=localhost&username=crowdom_user&password=crowdom_password" production
zf configure db-adapter "dbname=crowdom-test&username=test_user&password=test_password" testing
zf configure db-adapter "dbname=crowdom-dev&username=dev_user&password=dev_password" development
http://www.joelonsoftware.com/items/2009/09/23.html
http://www.joelonsoftware.com/articles/fog0000000018.html
it's ridiculous how intead of saying "create a file and put this inside", the author try to automate things with autogenerating scripts...
instead of saying "execute sqlite 3 < schema.sql", it writes a complicated php script to do the same...
To me it seems that I first have to finish my master of computer science to understand this tutorial.
And the 30 minutes (as said at the beginning of this mess) have passed some hours ago.
What worth is a tutorial, when there are obviously mistakes in it, so that you get stuck at least twice a page? And placing the correct lines of code in the comment section is not helpful.
My first impression of zend: complicate and just frustrating
At this point I will quit this
and try a piece of cake(php) or some fat free framework.
Bye and good luck
if (null === ($id = $guestbook->getId()))
// ^^^^^^^
while in the model we have:
public function setId($id)
{
$this->_id = (int) $id;
// ^^^^^^^
return $this;
}
[code]
Just a question ;>
http://pl.php.net/manual/en/language.types.null.php
I have something when I go to http://localhost:portNumber
but when I add http://localhost:portNumber/guestbook I have a 500 error.
There is nothing in the error.log or access.log.
I've still tried what said Plamena Marinova but it doesn't work for me.
Any clue?
I am struggling with this error:
An Error Has Occurred
Action 'configure' is not a valid action.
I do not have any clue. I have successfully used the command mentioned in previous chapters.
I am using this and getting the above error:
>zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH '/../data/db/guestbook.db'" production
I am struggling with this error:
An Error Has Occurred
Action 'configure' is not a valid action.
I do not have any clue. I have successfully used the command mentioned in previous chapters.
I am using this and getting the above error:
>zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH '/../data/db/guestbook.db'" production
But what is the real solution? I think it is a bug in code generation.
(Even this comment form is very unfriendly. )
Catchable fatal error: Argument 1 passed to Zend_Db_Select::__construct() must be an instance of Zend_Db_Adapter_Abstract, null given, called in G:\Program Files (x86)\Zend\ZendServer\share\ZendFramework\library\Zend\Db\Table\Select.php on line 76 and defined in G:\Program Files (x86)\Zend\ZendServer\share\ZendFramework\library\Zend\Db\Select.php on line 163
Thanks in advance for proving solution
Catchable fatal error: Argument 1 passed to Zend_Db_Select::__construct() must be an instance of Zend_Db_Adapter_Abstract, null given, called in G:\Program Files (x86)\Zend\ZendServer\share\ZendFramework\library\Zend\Db\Table\Select.php on line 76 and defined in G:\Program Files (x86)\Zend\ZendServer\share\ZendFramework\library\Zend\Db\Select.php on line 163
Thanks in advance for proving solution
"Action 'configure' is not a valid action"
for:
"zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH '/../data/db/guestbook.db'" -s production",
and renaming class not help( What a problem can be?
Make sure in your mysql configuration file(my.cnf)
skip-networking is commented.
comment out the line at my.cnf then restart mysql.
VEry very important. I was pulling my hair out for last two weeks. now got the Solution. It feels like I'm the king of the world :D
Catchable fatal error: Argument 1 passed to Zend_Db_Select::__construct() must be an instance of Zend_Db_Adapter_Abstract, null given, called in D:\xampp\php\PEAR\Zend\Db\Table\Select.php on line 76 and defined in D:\xampp\php\PEAR\Zend\Db\Select.php on line 163
I can't figure out what the error in the code could be. :-(
Anyone has already faced and fixed that one ?
thanks
Example should have a "red alert" for not being able to connect to the database
Example should have a "red alert" for not being able to connect to the database
PS:
The captcha system is crap...
1)it is human unreadable;
2) It always tell me that the message was posted...
3) I really must be blind... (just to say I've been trying lots of times now)
4) This is impossible... I got it right this time
5) #/¤/(Q/&¤=
Example should have a "red alert" for not being able to connect to the database
PS:
The captcha system is crap...
1)it is human unreadable;
2) It always tell me that the message was posted...
3) I really must be blind... (just to say I've been trying lots of times now)
4) This is impossible... I got it right this time
Example should have a "red alert" for not being able to connect to the database
PS:
The captcha system is crap...
1)it is human unreadable;
2) It always tell me that the message was posted...
3) I really must be blind... (just to say I've been trying lots of times now)
4) This is impossible... I got it right this time
Example should have a "red alert" for not being able to connect to the database
PS:
The captcha system is crap...
1)it is human unreadable;
2) It always tell me that the message was posted...
3) I really must be blind... (just to say I've been trying lots of times now)
4) This is impossible... I got it right this time
I am using Windows XP and iis 5.1
Please help me to cross out this hurdle.
In my view, this tutorial makes Zend a frustrating learning experience.
All Mapper classes extends from an abstract class, which refactor majority of the code. Some static functions make instanciation of mapper optional.
Be careful: this code works for PHP >= 5.3, because of static attribute.
------------------------------------------------------------------------------------------
abstract class Model_Mapper_Abstract
{
protected static $_dbTableName;
protected $_dbTable;
public function setDbTable($dbTable) {
if (is_string ( $dbTable )) {
$dbTable = new $dbTable ( );
}
if (! $dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception ( 'Invalid table data gateway provided' );
}
$this->_dbTable = $dbTable;
return $this;
}
/**
* @return Zend_Db_Table_Abstract
*/
public function getDbTable() {
if (null === $this->_dbTable) {
$this->setDbTable ( 'Model_DbTable_' . ucfirst(static::$_dbTableName) );
}
return $this->_dbTable;
}
public function find($id) {
$result = $this->getDbTable ()->find ( $id );
if (0 == count ( $result )) {
return null;
}
$row = $result->current ();
$model_className = "Model_" . ucfirst(static::$_dbTableName);
$customer = new $model_className ( $row->toArray () );
return $customer;
}
public function getAll() {
return ($this->fetchResults($this->getDbTable ()->fetchAll ()));
}
protected function fetchResults($resultSet) {
$entries = array ();
$model_className = "Model_" . ucfirst(static::$_dbTableName);
foreach ( $resultSet as $row ) {
$entries [] = new $model_className ( $row );
}
return $entries;
}
public static function getAllResults() {
$dbTable_className = 'Model_DbTable_' . ucfirst(static::$_dbTableName);
$model_className = "Model_" . ucfirst(static::$_dbTableName);
$dbTable = new $dbTable_className ( );
$resultSet = $dbTable->fetchAll ();
$entries = array ();
foreach ( $resultSet as $row ) {
$entries [] = new $model_className ( $row->toArray() );
}
return $entries;
}
public static function findById($id) {
$dbTable_className = 'Model_DbTable_' . ucfirst(static::$_dbTableName);
$dbTable = new $dbTable_className ( );
$result = $dbTable->find ( $id );
if (0 == count ( $result )) {
return null;
}
$row = $result->current ();
$model_className = "Model_" . ucfirst(static::$_dbTableName);
$object = new $model_className ( $row->toArray () );
return $object;
}
}
------------------------------------------------------------------------------------------
Having said that, here is the structure of a concrete Mapper. The save function is still here, because of the specificity for each class. This method can be implemented in abstract class thanks to toArray() method in the model (as Youssef Eldakar said), but I don't recommand it:
- responsibility of dababase schema must remains in Zend_DbTable and Mapper classes
- responsibility of Model classes must remains in Model_* and Mapper classes.
------------------------------------------------------------------------------------------
class Model_Map_GuestBook extends Model_Mapper_Abstract {
protected static $_dbTableName = "guestBook";
public function save(Model_Guestbook $guestbook)
{
$data = array(
'email' => $guestbook->getEmail(),
'comment' => $guestbook->getComment(),
'created' => date('Y-m-d H:i:s'),
);
if (null === ($id = $guestbook->getId())) {
unset($data['id']);
$this->getDbTable()->insert($data);
} else {
$this->getDbTable()->update($data, array('id = ?' => $id));
}
}
}
------------------------------------------------------------------------------------------
Last Tip: here is some functions I suggest to integrate in mapper during development phase. There is no value-added code here, but this permit a full completion (Type Hinting) support in environments like PHP Eclipse, Zend Studio...
------------------------------------------------------------------------------------------
/**
* @return Model_GuestBook
**/
public function find($id) {
return parent::find($id);
}
/**
* @return Model_GuestBook
**/
public static function findById($id) {
return parent::findById($id);
}
/**
* @return Model_DbTable_GuestBook
**/
public function getDbTable() {
return parent::getDbTable();
}
------------------------------------------------------------------------------------------
Hope this helps :)
Regards,
Damien THIESSON
./configure --with-apxs2=/usr/local/apache/bin/apxs --with-mysql --enable-pdo --with-pdo-mysql=shared
After that I had to add the pdo-mysql.so extension to php.ini, and it worked.
-Sean
Maybe I am mission something but shouldn't the find method instantiate the model as the fetchAll method does in it's foreach loop?
Or should I create an instance of the guestbook model before calling the find so that I can pass the second parameter.
*** application/models/GuestbookMapper.php (web)
--- application/models/GuestbookMapper.php (maybe)
***************
*** 42,44 ****
! public function find($id, Application_Model_Guestbook $guestbook)
{
--- 42,44 ----
! public function find($id)
{
***************
*** 49,50 ****
--- 49,51 ----
$row = $result->current();
+ $guestbook = new Application_Model_Guestbook();
$guestbook->setId($row->id)
Comments: Sagt mal wollt Ihr hier überhaupt hilfe erhalten, bitte immer OS und Datenbank Typ angeben, eine Baumansicht der Verzeichnisse würde auch helfen.
Meine Schwierigkeiten bisher: (Vista, MySql | SQLITE)
Erstes war zu erkennen das man den (database excel sheet) nicht wie angegeben bei Windows verwenden kann sondern mittels c:\Zend\Apache2\meineTest\> zf create db-table Guestbook guestbook.
Tja und zwischendurch habe ich bemerkt das die NaviMenüpunk nach http://localhost/test/public/guestbook weist.
Fazit: Diese Beschreibung sollte man ignorieren da auch die Comments grösstenteils unbrauchbar sind. Es stellt sich jetzt für mich die Frage doch weiter ein eigenes Framework zu nutzen und weiter meine Lebenszeit mit eigenem KauderwelchFramework zu arbeiten.
Im übrigen gibt es gute beschreibungen wie man gute beschreibungen anfertigt. Es müsste ein Gesetz dagegen geben solche Schriftstücke auf die Menschheit loszulassen.
To get mysql working I had to add these lines to my php.ini:
extension=pdo.so
extension=pdo_mysql.so
and these lines to my application.ini under [production]
resources.db.adapter="PDO_MYSQL"
resources.db.params.host="localhost"
resources.db.params.username="bobandst"
resources.db.params.password="p1ssw2rd"
resources.db.params.dbname="bobandst_Main"
I also had to add this line to my .htaccess file to get the development environment:
SetEnv APPLICATION_ENV development
My application still seems to have issues connecting to the database, are there more config lines that I am missing?
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $key => $value) {
$method = 'set' . ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
If you use DB then class constructor mus have
class Application_Model_Guestbook
{
protected $_comment;
protected $_created;
protected $_email;
protected $_id;
public function __construct(array $options = null)
{
parent::__construct($options); // This line must be to set DB adapter
if (is_array($options)) {
$this->setOptions($options);
}
}
}
I am using Windows 7 Zend Server CE
Thanks!!!
$data = array(
'email' => $guestbook->getEmail(),
'comment' => $guestbook->getComment(),
'created' => date('Y-m-d H:i:s'),
//--> maybe here we should be adding 'id'=> $guestbook->getId();
);
if (null === ($id = $guestbook->getId())) {
unset($data['id']);
$this->getDbTable()->insert($data);
} else {
$this->getDbTable()->update($data, array('id = ?' => $id));
}
Why are we 'unset'-ing a variable that was never set? Should we add $data['id'] first? Are we assuming Id is an auto_increment field? That's why we are not inserting it to the table? What am I missing here?
@Youssef -- You seem to be exposed to this as well by trying to reflect on the incoming array in order to derive the table's column names. You should consider always implementing a mapper between domain objects and the storage of the data.
Ok, I wrote reams of text and then realized that I should Google Data Mapper Pattern to see if anybody said it more succinctly so I deleted mine and I direct you to Martin Fowler's description... (the point that I had written reams about was collection of objects in objects. This is something that can be handled by a mapper -- although if you're going to be doing this extensively, it would be worth looking into a full-blow ORM solution like Hibernate, or Doctrine/Outlet)
http://martinfowler.com/eaaCatalog/dataMapper.html
This is something that I don't understand either. Can someone please clarify this for us?
I wonder how this code ended up in here. Right now it is clearly unnecessary, so I will not implement this line of code in my applications.
But hey, someone willing to relief us with the thruth would be welcome, 'cause this code is bugging me. LOL
I am using PDO_MYSQL as my adapter. I have followed the tutorial to the letters.
At a point, it says to create application/models/GuestbookMapper.php and put the following code
class Application_Model_GuestbookMapper
{
public function save($model);
public function find($id, $model);
public function fetchAll();
}
Then it say to run this command
zf create model GuestbookMapper
The tutorials claims to insert additional methods. But in my case, it emptied the my GuestbookMapper class with this
class Application_Model_GuestbookMapper
{
}
Same goes with another command zf create model Guestbook. It empties the scripts, with just plain class defination.
Please help me !
<Directory "C:\Zend\Apache2/htdocs/Quickstart/public">
DirectoryIndex index.php
AllowOverride All
Order allow,deny
Allow from all
</Directory>
I didn't pay attention - I only added:
<VirtualHost *:80>
ServerName hello.localhost
DocumentRoot "C:\Zend\Apache2/htdocs/newapp/HelloWorld/public"
#DocumentRoot "C:\Zend\Apache2/htdocs/Quickstart/public"
SetEnv APPLICATION_ENV development
</VirtualHost>
I hope this can help others with the same issue ; )
For those who r using Abyss web server, dun forget to set the URL rewriting.. if not you will get error 404.
http://www.aprelium.com/abyssws/articles/urlrewriting-modrewrite-conversion.html
Why isn't ?
zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH '/../data/db/guestbook.db'" production
$resultSet = $this->getDbTable()->fetchAll();
$entries = array();
foreach ($resultSet as $row)
{
$entry = new Application_Model_Guestbook();
foreach ($row as $key => $value)
{
$method = 'set'.ucfirst($key);
$entry->$method($value);
}
$entries[] = $entry;
}
return $entries;
Thanks the community for the best framework of the world!
JCROOT
La unica manera de hacerlos andar fue asi:
zf configure db-adapter "adapter=Mysql&dbname=APPLICATION_PATH '/../data/db/guestbook.db' " -s production
cambiando para cada section el archivo y el valor de -s.
Espero le sirva a alguien
ex: 127.0.0.1/asdf/jkl/public/
in .htaccess add
RewriteBase /asdf/jkl/public/
you'll get a 404 w/o
The tutorial then:
- fails to tell you exactly where to put files (like the database and SQL/loader scripts)
- contains incomplete code (people have to insert the <?php ?> tags themselves)
- doesn't explain enough as it goes along - I feel like I'm learning how to build a very simple app without the tutorial explaining WHY I'm doing certain things, like creating the Application_Model_GuestbookMapper class, or creating a huge long script to set up my database
And now...on top of all that...I'm stuck because the load.sqlite.php script won't define the APPLICATION_PATH and so the script can't find the application.ini
Do I really want to learn a framework for developing apps when the developers of the framework can't even write a decent tutorial?
1/2 hour? It's taken me all day to get this far and I'm giving up.
it started from basic knowledge such as folder structure or cover all the area
of web application like database connectivity ,query to database.
please reply as soon as possible It is argent.
But there's a few lines i don't get:
public function find($id, Application_Model_Guestbook $guestbook){
$result = $this->getDbTable()->find($id);
if (0 == count($result)) {
return;
}
$row = $result->current();
$guestbook->setId($row->id)
->setEmail($row->email)
->setComment($row->comment)
->setCreated($row->created);
}
1) How is one supposed to make use of that function?
So i assume i have to be like
$table = new Application_Model_GuestbookMapper();
$row = new Application_Model_Guestbook();
$row_that_i_want = $table->find(42, $row);
Even if that were correct, the code would still not du anything? It does not give anything back!? There is no return, so that assignment has no use...
2) Then what i don't understand either with the three-layered abstraction is,
We have a tableMapper-class
We have a tableRowset-class
We have a tableRow-class
The only thing that extends something from the framewok is the tableMapper
Shouldn't the tableRowset and tableRow extend the specified Zend-Classes, too?
Because:
How am i supposed to built relationships between tables with the code provided above?
I can assign the relationships inside the tableMapper class, but how do i access them?
I would want to be like:
$table = new tableMapper();
$row = $table->find(1); // eventually $table->find(1)->current();
Lets say i got an Author with this, from this author i want to retrieve all books
$row->getBooks();
The getBooks(); funktion in the rowclass would call something like findDependentRowset();
But the rowClass doesn't know that functiuon, als there is no connection.
Now i have built relationships of tables in a previous project where i simply used a rowsetClass and a rowClass - with the tableMapper on top i don't know how i would be able to do this at all. it's just a little bit weird.
As many people have problems with understanding this quickstart, i think the quality should be checked again
And please just use mysql or a sql server - no one wants to "copy and see how it works" with a sqLite file.. ;)
Try looking at the vhost configuration. If AllowOverride is not set to All, it will not work!
I agree with most of the people here who are having issues with Mysql as there is nothing specific given for that.
I request you guys to please post or edit this article and mention , how to configure the quickstart project with mysql.
I will be waiting
Noddy
http://www.phpeveryday.com/articles/Zend-Framework-Basic-Tutorial-P840.html
http://www.survivethedeepend.com/
I appreciate the good intentions of the author, but the results are very frustrating for programmers trying to learn this framework.
Why not use MySQL?
Why create a twisted script to create the database?
Why do I have to guess the directories I have to use?
Why make assumptions?
Please, keep it simple, and be thorough in the explanation. I am not giving up on ZF, but I am really disappointed in the Zend communitiy efforts to educate the new comers.
In adition you cannot create any Database in this MySQL-Server.
How can one test their application if one have no right to create the database?
But nice to read, that I'm not the only frustrated one.
I find that there should be small steps instead of making a high level tutorial especially while talking about a quick tutorial for beginners.
I did this tutorial and everything worked after setting up my httpd.conf und my paths for php and zf tool. But if I send up my form to write into my database there was a problem and I got error "page not found".Look at code below:
if ($this->getRequest()->isPost())
{
if ($form->isValid($request->getPost()))
{
$model = new Application_Model_Guestbook($form->getValues());
// line that doesn't work is here:
$model->save();
return $this->_helper->redirector('index');
}
}
I solved it this way:
if ($this->getRequest()->isPost())
{
if ($form->isValid($request->getPost()))
{
$model = new Application_Model_Guestbook($form->getValues());
// my solution
$guestbook = new Application_Model_GuestbookMapper();
$guestbook->save($model);
// end of my solution
return $this->_helper->redirector('index');
}
}
I'm not the real ZF-Crack. I see, the Guestbook mapper is initiated in the IndexAction(). Now I'm not sure how PHP handles this. Does PHP create this instance of class only for the IndexAction() or does it create this instance global? In second case it must work without my solution.... Is there anyone with a better solution or the same problem? (And sorry for my bad english.. :) )
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = ""
resources.db.params.dbname = "my_database_name"
resources.db.isDefaultTableAdapter = true
and execute below queries in your mysql database
CREATE TABLE guestbook (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
email VARCHAR(32) NOT NULL DEFAULT 'noemail@test.com',
comment TEXT NULL,
created DATETIME NOT NULL
);
CREATE INDEX id ON guestbook (id);
INSERT INTO guestbook (email, comment, created) VALUES
('ralph.schindler@zend.com',
'Hello! Hope you enjoy this sample zf application!',
NOW());
INSERT INTO guestbook (email, comment, created) VALUES
('foo@bar.com',
'Baz baz baz, baz baz Baz baz baz - baz baz baz.',
NOW());
Keep other classes same as mentioned above.
0. Please remember to surround the load.sqlite.php content with <?php and ?>
1. In case you see "The sqlite driver is not currently install"
For basic LAMP installation you might need to do
>sudo apt-get install php5-sqlite
To install sqlite driver.
2. In case you see "SQLSTATE[HY000] [14] unable to open database file
Remember to move data and scripts in the correct folder
Put "scripts" and "data" folders in the same folder of
"application data docs library public scripts tests"
where there are:
scripts/load.sqlite.php
data/db/
I don't know if it's only me but i find setting up Zend to work is a tedious task. instead of making the development faster, just slows it down plus this messed up tutorial. Nice!
- you set the absolute path to your installation on both the DocumentRoot and Directory directive in your httpd.conf.
- you have Options +FollowSymLinks in either your .htaccess or your httpd.conf VirtualHost > Directory directive.
hth
This is done in the Apache configuration file: "C:\...\xampp_dir\apache\conf\httpd.conf"
I am Mrs Antonia Benson , I work in Sunshine Dairy Foods Company here in Canada ,
we need workers from all parts of the world to join the company , whether skill or
unskilled they are all qualified to join the company .
You can also invite any of your friends and relatives to join us either the branch
in Canada or United kingdom.
All approved applicants are to be granted free air plane ticket and free
accommodation , applicants are only responsible for work permit visa requirements
with the Canada Immigration Bureau here upon received of employment form.
Contact us through this email:sunshineemploymentinfo@inmail.sk , or
(sun.shinecompany@yahoo.ca)
Your best Cooperation is highly appreciated .
Mrs Antonia Benson,
Employment Consultant Officer ,
Human Resources Department .
150 - 6TH AVENUE SW CALGARY
ALBERTA T2P 3Y7,CANADA.
Ouch, do not forget to realize, this whole project is open source and free.
Thanks for this tutorial guys!! Loving ZF!
Ein kleiner Schönheitsfehler beim INSERT von data.sqlite.sql
INSERT INTO guestbook (email, comment, created) VALUES
('ralph.schindler@zend.com',
'Hallo! Hoffentlich geniesst Ihr dieses Beispiel einer ZF Anwendung!
DATETIME('NOW'));
Es fehlt das ' und das komma danach!
'Hallo! Hoffentlich geniesst Ihr dieses Beispiel einer ZF Anwendung!',
gruß
http://www.phpeveryday.com/articles/Zend-Framework-Basic-Tutorial-P840.html
I skipped the 'zf configure db-adapter' portion and simply added the mysql details in the application.ini as mentioned above:
I appreciate there are a lot of comments (and good info) above and maybe as a result the tutorial may have been amended over time to where it is now.
New users running through this for the first time might simply give up after reading all the comments, however, it's really not that bad :)
There is an answer at the bottom of this message.
Scroll down if you're in a hurry.
--------------- Problem --------------------
Running zf configure db-adapter on windows with the arguments given in this tutorial, does not work.
There are a lot of comments about not being able to run the commands given to configure the db-adapter on windows machines.
The commands given are formatted for linux and aren't easily converted.
--------------- Issue -----------------
Command Given:
% zf configure db-adapter \
> 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' \
> production
The trick is that the argument:
'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"'
contains spaces, double quotes, and the & symbol.
--------------- Working out the solution ------------------
spaces delimit arguments. Resolve by wrapping in double quotes.
& is used when writing multiple commands on a single line. as in
dir&tree
will give you a directory listing followed by a tree. Resolve by escaping the & with ^ when the & lies outside of a literal string.
I'm assuming the intention of wrapping the entire argument in single quotes on linux is to pass it as a literal string. On windows you pass an argument as a literal string by wrapping it with double quotes. So first convert the single quotes to double quotes.
"adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db""
Then notice that the command won't work. This is because the argument contains double quotes and ends up being parsed as several arguments instead of one.
So step 2, find all the double quotes inside the argument and double them.
"adapter=PDO_SQLITE&dbname=APPLICATION_PATH ""/../data/db/guestbook.db"""
Now you might be thinking about escaping the &, don't. The & is interpreted literally, not as a control character or anything special. If the & or any other special character ends up outside of the literal string, then you need to escape them with ^.
--------------- Solution ---------------------------
PLEASE INCLUDE THIS ALTERNATE SET OF COMMANDS FOR WINDOWS USERS. :D
The whole thing ends up converting to this:
C:\path\to\project\root\> zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH ""/../data/db/guestbook.db""" production
C:\path\to\project\root\> zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH ""/../data/db/guestbook-testing.db""" testing
C:\path\to\project\root\> zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH ""/../data/db/guestbook-dev.db""" development
********** convert C:\path\to\project\root\ to the location of your project folder ( parent of application folder ) **********
--------------- Results ---------------
[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
resources.view[] =
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
[staging : production]
[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
********** Notice that **********
resources.db.adapter
and
resources.db.params.dbname
both have exactly the same values as given in the tutorial when using the commands given in my solution.
----- Side note --------
Could we run zf.php with the CLI and avoid a lot of confusion? Interactive mode is still broken on windows machines as far as I know, but I work around it with:
<?php
while (1) {
fputs(STDOUT, "\r\nPHP_MODE: ");
eval(trim(fgets(STDIN)));
}
?>
I save that to a file called interactive.phps and start it with:
C:\path\to\php.exe -f "C:\path\to\interactive.phps"
and php interprets everything I type. There's no error handling, so if you type anything wrong the window will close. When you're done type exit; and you'll leave PHP_MODE and be back to the shell you were in before.
If say. . . the environment variables could be set with a php file and this snippet had some sort of error handling then we could forget about a lot of differences between linux and windows command line syntax. . . maybe. . .
... or maybe a web interface for common . . . I don't know what I'm getting into. . ..
--------------- Quick Solution For the Impatient ---------------------------
PLEASE INCLUDE THIS ALTERNATE SET OF COMMANDS FOR WINDOWS USERS. :D
The whole thing ends up converting to this:
C:\path\to\project\root\> zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH ""/../data/db/guestbook.db""" production
C:\path\to\project\root\> zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH ""/../data/db/guestbook-testing.db""" testing
C:\path\to\project\root\> zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH ""/../data/db/guestbook-dev.db""" development
********** convert C:\path\to\project\root\ to the location of your project folder ( parent of application folder ) **********
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
APPLICATION_PATH seems to be a sibling folder of the folder containing index.php, specifically it would resolve to quickstart/application/ unless intentionally changed.
So APPLICATION_PATH = quickstart/application
then in application.ini we set the databases for test dev and production to all go into one folder located at:
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
APPLICATION_PATH/../data/db/guestbook-dev.db
quickstart/application/../data/db/guestbook-dev.db
quickstart/data/db/guestbook-dev.db
This is also the file structure in the zip file of the completed tutorial. So it is safe to assume that the folders "data" and "application" are siblings whose parent is the folder "quickstart".
Please edit this section of the tutorial:
---- Quote ------
Note that the database(s) will be stored in data/db/. Create those directories, and make them world-writeable. On unix-like systems, you can do that as follows:
% mkdir -p data/db; chmod -R a+rwX data
On Windows, you will need to create the directories in Explorer and set the permissions to allow anyone to write to the directory.
At this point we have a connection to a database; in our case, its a connection to a Sqlite database located inside our application/data/ directory. So, let's design a simple table that will hold our guestbook entries.
---- End Quote -----
Specifically, the directories confuse me and there are other comments saying the same thing. If you could change the reference to "data/db/" into "quickstart/data/db/" then it would be very clear where the data directory belongs. Also, change the reference to "application/data/". I didn't see any instruction to create this folder and it was also not present in the completed project.
quickstart was the name of the initial folder we made on the second page of this tutorial. It serves as an effective point of reference when we're going through this tutorial where we're not familiar with the file structure or methods or basically anything. I don't even remember what I was reading because I've wasted so much time reading typos and converting linux command syntax into something that works on windows so I could use the batch file referenced in these very instructions.
I AM NOT A HAPPY DUCK. :(
Is the Zend Framework really worth all this effort?
I will be back to try doing all this by hand again. Don't delete my comments. I'll need them for next time. . .
The writer for this had alot of content to cover, and cannot compensate for everything that everyone may or may not already know. If you're even attempting to learn a framework then you should already have some common coding sense and problem solving skills or else you failed before you even came here.
Guestbook Entries: <br />
<dl>
<?php foreach ($this->entires as $entry): ?>
<dt><?php echo $this->escape($entry->email) ?></dt>
<dd><?php echo $this->escape($entry->comment) ?></dd>
<?php endforeach ?>
</dl>
but ther is:
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>
Best regards
Krzysiek
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "localhost"
resources.db.params.username = "username"
resources.db.params.password = "pass"
resources.db.params.dbname = "dbname"
resources.db.isDefaultTableAdapter = true
Try just modifying localhost to 127.0.0.1 like the following:
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "127.0.0.1"
resources.db.params.username = "username"
resources.db.params.password = "pass"
resources.db.params.dbname = "dbname"
resources.db.isDefaultTableAdapter = true
This way worked for me.
In my case I am using a mac with Zend Studio 8 and Zend Server 5.5. This quickstart is the zend framework example in Zend studio and almost everything is already written. but I wanted to get the php script to run and got stuck a bit trying to get this include_path to work.
At the end, I changed the APPLICATION_PATH and it works :
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
set_include_path(implode(PATH_SEPARATOR, array(
APPLICATION_PATH . '.:/usr/local/zend/share/ZendFramework/library',
get_include_path(),
)));
good luck guys ;)
please streamline it.
thank you.
What's problem?
public function getOptions(array $exceptions = array())
{
$data = array();
foreach ($this->options as $key => $value) {
$data[$key] = $this->__get($key);
}
return array_diff_key($data, array_flip($exceptions));
}
which allows me to get all of the data with one call rather than individually grabbing all options to store in a data array during something like a save:
public function save(Application_Model_Guestbook $guestbook)
{
$data = array(
'email' => $guestbook->getEmail(),
'comment' => $guestbook->getComment(),
'submitted' => date('Y-m-d H:i:s'),
);
public function save(Application_Model_Guestbook $guestbook)
{
$data = $guestbook->getOptions(array('id'));
Please, someone can tell me from where came these 'set' and 'mapper' in application/models/Guestbook.php?
public function __set($name, $value) {
//This set I'm asking
$method = 'set' . $name;
//This mapper I'm asking
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid guestbook property');
}
$this->$method($value);
}
Also I would like suggest to Zend's people who make the quick start to write comments in the main example code. Maybe it can help better newbies like me.
Thanks!
1. just copy the 3 files data.sqlite.sql, schema.sqlite.sql and load.sqlite.php in public than
2. excute it from the browser just li this
http://quickstart.local/load.sqlite.php?w
you should see
Writing Database Guestbook in (control-c to cancel): 5 4 3 2 1 Database Created
don't mess with CLI, you will waste your time just like I did.
Bye
p.s.
PHP Version 5.3.2-1ubuntu4.10
eclipse Helios (still problem using zend CE modules)
really wasted hours an hours to learn how to connect to db only.
Still no success
<?php
... as the first line of the file load.sqlite.php and add as the last line of this file ...
?>
probably obvious to experience php programers ... but not :)
The requested URL /quickstart/guestbook was not found on this server."
this complete source code http://framework.zend.com/demos/ZendFrameworkQuickstart.zip doesn't work too.
I think this "quickstart" tutorial is poorly written and not properly tested in the real world.
I'm not an inexperienced php programmer and I'm struggling to get this to work. Very poor Zend....
the document is very good, however few questions and hints arise that I want to share with you all.
First of all, my programming idea is DOWIN - Do Only What Is Necessary. An illustration: there is a framework-builtin mechanism that you may use 'as is' or modify/interface for your own. Do you REALLY need interfacing this mechanism? YES? Then go on. NO? Then leave it as it is, please.
Zend framework is a BRILLIANT thing, it's a diamond among the MVC frameworks. Thanks to the hard work of many brilliant programmers, developers, analysts, managers, it contains anything a PHP MVC programmer needs.
As for the models described in the article, let's see what we want to achieve by making them. Separation of data logic and data storage mechanisms? Then we/you are right about making separate "mapper" classes for them. Also, separation of mappers from classes extending Zend_Db_Table is much safer than introducing our own functionalities to the class that contains thousands of lines of code; at least we don't risk breaking anything defined in the parent, abstract class. So a "has-a" solution is as great as can be: we just make a class for table defining the database details, pack it in a nice and tidy suitcase of getter/setter, and we find it a shelf inside our model. Great.
As for the model for data item: I really think it's unnecessary to create getter/setter methods for all data.
For the basic functionality, it's absolutely reduntant. So according to DOWIN, let's think whether we really-really
need some extra functionality for each field? Do we? Then let's create getters and/or setters for the fields
we need the functionality, leaving others alone. It's enough to create class properties corresponding to each field
and checking in __get()/__set() methods if they exist in the class. For getters/setters as getXXXX() and setXXXX()
we/you can use __call() magic as well.
And now...on top of all that...I'm stuck because the load.sqlite.php script won't define the APPLICATION_PATH and so the script can't find the application.ini
It is because the script folder for load.sqlite.php, schema.sqlite.sql and data.sqlite.sql should be in the same folder as:
"application data docs library public scripts tests"
server {
listen 80;
server_name vac.local;
access_log /srv/projects/php/vac.local.access.log;
error_log /srv/projects/php/vac.local.error.log;
root /srv/projects/php/vac/public;
location / {
index index.php;
}
# serve static files directly
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ {
access_log off;
expires 30d;
}
location ~ \.htaccess {
deny all;
}
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /srv/projects/php/vac/public$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
include /etc/nginx/conf/fastcgi_params;
}
}
==Step 1: add adapter
zf configure db-adapter 'adapter=PDO_MYSQL&dbname=guestbookdb' production
zf configure db-adapter 'adapter=PDO_MYSQL&dbname=guestbookdb_test' testing
zf configure db-adapter 'adapter=PDO_MYSQL&dbname=guestbookdb_dev' development
==Step2: edit sql, create schema & data
1)
mkdir scripts
2)
vi scripts/schema.mysql.sql
DROP DATABASE IF EXISTS guestbookdb;
CREATE DATABASE guestbookdb;
USE guestbookdb;
DROP TABLE IF EXISTS guestbook;
SET @saved_cs_client = @@character_set_client;
SET character_set_client = 'utf8';
SET character_set_connection= 'utf8';
SET character_set_results='utf8';
CREATE TABLE guestbook (
id int NOT NULL AUTO_INCREMENT,
email varchar(32) NOT NULL DEFAULT 'noemail@test.com',
comment TEXT NULL,
created DATETIME NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE INDEX id ON guestbook(id);
3)
vi scripts/data.mysql.sql
USE guestbookdb;
INSERT INTO guestbook (email, comment) VALUES
('ralph.schindler@zend.com',
'Hello! Hope you enjoy this sample zf application!');
INSERT INTO guestbook (email, comment) VALUES
('foo@bar.com',
'Baz baz baz, baz baz Baz baz baz - baz baz baz.');
4) execute:
mysql -uroot -p < scripts/schema.mysql.sql
mysql -uroot -p < scripts/data.mysql.sql
==Step3: just as standard steps to create following
zf create db-table Guestbook guestbook
zf create model GuestbookMapper
zf create model Guestbook
zf create controller Guestbook
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = ""
=========nginx config=========
server {
listen 8000;
server_name quickstart.local;
location / {
root /home/thes/www/app/quick2/public;
index index.php;
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
}
location ~ \.php$ {
root /home/thes/www/app/quick2/public;
fastcgi_connect_timeout 600;
fastcgi_read_timeout 600;
fastcgi_send_timeout 600;
fastcgi_buffer_size 4k;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/thes/www/app/quick2/public/$fastcgi_script_name;
fastcgi_param APPLICATION_ENV development;
#fastcgi_param include_path /home/thes/www/app/quickstart/library/Zend;
include fastcgi_params;
}
}
nohup /usr/local/bin/php-cgi -b localhost:9000 &
for windows the right usage is as follows (you have to change the order of the quotation marks):
zf configure db-adapter "adapter=PDO_SQLITE&dbname=APPLICATION_PATH '/../data/db/guestbook-dev.db' " development
Best regards
<b>Axel Arnold Bangert</b>
Wolfstrasse 2
52134 Herzogenrath, 14.01.2012
in the above script data.sqllite is a syntax error at the end of line 8 (missing quotation mark and missing komma!
Best regards
Axel Arnold Bangert
Wolfstrasse 2
52134 Herzogenrath, 14.01.2012
INSERT INTO guestbook (email, comment, created) VALUES
('ralph.schindler@zend.com',
'Hallo! Hoffentlich geniesst Ihr dieses Beispiel einer ZF Anwendung',
DATETIME('NOW'));
public function __set($name, $value)
{
$method = 'set' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
if(array_key_exists('_'.$name, get_object_vars($this))){
$this->$name = $value;
return $value;
}
throw new Exception('Invalid entity property');
}
$this->$method($value);
}
public function __get($name)
{
$method = 'get' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
if(array_key_exists($name, get_object_vars($this))){
return $this->$name;
}
throw new Exception('Invalid entity property');
}
return $this->$method();
}
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $key => $value) {
echo $key;
$method = 'set' . ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}elseif(array_key_exists('_'.$key, get_object_vars($this))){
$this->$key = $value;
}else{
throw new Exception('Invalid entity property');
}
}
return $this;
}
- First, proper IDEs come with getter/setter generation build in. So no need to write them!
- I prefer if my IDE can hint me about what properties i can get/set, in other words, hint me what methods i can use on a certain object. No way an IDE can still hint you with above code.
- Your code allows access to all properties. In many, many use-cases there's properties you dont want other code to be able to access.
- .... plenty of more reasons
the commands executed on command-line assume this kind of folder tree (when followed from the start of the guide):
- quickstart/layouts/scripts/ (including load.sqlite.php and other .sql files) should be located in the quickstart directory quickstart/scripts/ (its obvious because layouts is all about layouts). So I guess this is also wrong in the application/configs/application.ini file:
...
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
...
- also data/db/ should be located in the quickstart directory quickstart/data/db
This solved the problem with:
% php scripts/load.sqlite.php --withdata
... and created sqlite database (for sqlite database you have to enable sqlite in the php.ini file).
This documentation is really bad and complicated which also makes the use of Zend Framework difficult. I didn't even bother to follow up to the end of this manual. It is reasonable to use only some parts of the framework and make some customised MVC architecture of your own. There are alot better and simpler explanations how to use Zend Framework out there, then it is provided in here.
Cheers
http://www.webpixel.gr/blog/zend-quickstart-tutorial
this command is totaly ignored by my windows... normal ?
I Have a problem with db scripts
my data file are in quickstart directory, i have check thausend time all my file but i have always this error :
command : php scripts/load.sqlite.php
' > Writing blabla:
AN ERROR HAS OCCURED
SQLSTATE[HY000]: general error: 1 near "'< CREATE": syntax error
Why, i check all my file no error to the tuto ?
directory
quickstart -> scripts
data.sqlite.sql
INSERT INTO guestbook (email, comment, created) VALUES
('ralph.schindler@zend.com',
'Hello! Hope you enjoy this sample zf application!',
DATETIME('NOW'));
INSERT INTO guestbook (email, comment, created) VALUES
('foo@bar.com',
'Baz baz baz, baz baz Baz baz baz - baz baz baz.',
DATETIME('NOW'));
schema.sqlite.sql
CREATE TABLE guestbook (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
email VARCHAR(32) NOT NULL DEFAULT 'noemail@test.com',
comment TEXT NULL,
created DATETIME NOT NULL
);
load.sqlite.php
<?php
/**
* Script pour créer et charger la base
*/
// Initialise le chemin vers l'application et l'autoload
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
set_include_path(implode(PATH_SEPARATOR, array(
APPLICATION_PATH . '/../library',
get_include_path(),
)));
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();
// Definit des options CLI
$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',
));
try {
$getopt->parse();
} catch (Zend_Console_Getopt_Exception $e) {
// Mauvaises options passées: afficher l'aide
echo $e->getUsageMessage();
return false;
}
// Si l'aid eest demandée, l'afficher
if ($getopt->getOption('h')) {
echo $getopt->getUsageMessage();
return true;
}
// Initialise des valeurs selon la présence ou absence d'options CLI
$withData = $getopt->getOption('w');
$env = $getopt->getOption('e');
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (null === $env) ? 'development' : $env);
// Initialise Zend_Application
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
// Initialise et récupère la ressoucre DB
$bootstrap = $application->getBootstrap();
$bootstrap->bootstrap('db');
$dbAdapter = $bootstrap->getResource('db');
// Informons l'utilisateur de ce qui se passe (nous créons une base de données
// ici)
if ('testing' != APPLICATION_ENV) {
echo 'Writing Database Guestbook in (control-c to cancel): ' . PHP_EOL;
for ($x = 5; $x > 0; $x--) {
echo $x . "\r"; sleep(1);
}
}
// Vérifions si un fichier pour la base existe déja
$options = $bootstrap->getOption('resources');
$dbFile = $options['db']['params']['dbname'];
if (file_exists($dbFile)) {
unlink($dbFile);
}
// Chargement du fichier de la base de données.
try {
$schemaSql = file_get_contents(dirname(__FILE__) . '/schema.sqlite.sql');
// utilise la connexion directement pour charger le sql
$dbAdapter->getConnection()->exec($schemaSql);
chmod($dbFile, 0666);
if ('testing' != APPLICATION_ENV) {
echo PHP_EOL;
echo 'Database Created';
echo PHP_EOL;
}
if ($withData) {
$dataSql = file_get_contents(dirname(__FILE__) . '/data.sqlite.sql');
// utilise la connexion directement pour charger le sql
$dbAdapter->getConnection()->exec($dataSql);
if ('testing' != APPLICATION_ENV) {
echo 'Data Loaded.';
echo PHP_EOL;
}
}
} catch (Exception $e) {
echo 'AN ERROR HAS OCCURED:' . PHP_EOL;
echo $e->getMessage() . PHP_EOL;
return false;
}
// Ce script sera lancé depuis la ligne de commandes
return true;
?>
lo
CREATE INDEX "id" ON "guestbook" ("id");
I had to browse to http://quickstart.local/index.php/guestbook.
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>
To fix it, I had to remove $this->escape() and use the Guestbook getter on comment and email. It now looks like:
Guestbook Entries: <br />
<dl>
<?php foreach ($this->entries as $entry): ?>
<dt><?php echo $entry->getEmail(); ?></dt>
<dd><?php echo $entry->getComment(); ?></dd>
<?php endforeach ?>
</dl>
I don't know is it's a secure way of doing it (removing the escape() doesn't look like a good idea) but it's the only way I found to make the entries show up.
Hope this helps.