実際の世界のアプリケーションでは、データベースからコンテンツを表示するのは共通のタスクです。またコンテンツが何千もの項目を含む検索結果である場合を想像してください。うたがいなく、巨大なリストになり、メモリーの消費量が多くなりユーザーは正しい項目を見つけづらくなります。この問題に対してコンテンツ表示の編成が必要でページ分割が手助けになります。
Doctrineは高度で柔軟なページャーパッケージを実装します。これによってリストを複数のページに分割できるだけでなく、ページリンクのレイアウトもコントロールできます。この章では、ページャーオブジェクトの作り方、ページャースタイルをコントロール仕方を学び、最後にページャーレイアウトオブジェクト - Doctrineの強力なページリンク表示機能の概要を見ます。
クエリのページ分割はクエリ自身と同じぐらいシンプルで効率的にできます。Doctrine_Pagerはクエリを処理してページ分割することを担います。次の小さなピースのコードで確認しましょう:
// 初期値を定義する
$currentPage = 1;
$resultsPerPage = 50;
// ページャーオブジェクトを作成する
$pager = new Doctrine_Pager(
Doctrine_Query::create()
->from( 'User u' )
->leftJoin( 'u.Group g' )
->orderby( 'u.username ASC' ),
$currentPage, // リクエストの現在のページ
$resultsPerPage // (オプション)ページごとの結果数。デフォルトは25
);
この場所までは、このコードは古いDoctrine_Queryオブジェクトと同じです。唯一の違いは新しい2つの引数が存在することです。これら2の引数に加えて古いクエリオブジェクトはDoctrine_Pagerオブジェクトによってカプセル化されます。この段階では、Doctrine_Pagerはページ分割をコントロールするために必要な基本データを定義します。ページャーの実際のステータスを知りたい場合、行うべきことはこれが既に実行されたかどうかチェックすることです:
$pager->getExecuted();
Doctrine_Pagerによって提供される任意のメソッドにアクセスしようとする場合、Pagerがまだ実行されなかったことを報告するDoctrine_Pager_Exceptionが投げられるのを経験することになります。実行されたとき、Doctrine_Pagerは情報を検索する強力なメソッドを提供します。APIの使い方はこのトピックの最後に並べてあります。
クエリを実行するには、プロセスは現存するDoctrine_Query実行呼び出しと似ています。オプションのパラメータを含む構文の完全な例は次の通りです:
$items = $pager->execute([$args = array() [, $fetchType = null]]);
foreach ($items as $item) {
// ...
}
レコードクエリがカウンタークエリと異なる特別なケースがあります。この状況に対応するために、Doctrine_Pagerにはカウントしてから実行できるようにするメソッドがあります。最初に行わなければならないのはカウントクエリを定義することです:
$pager->setCountQuery($query [, $params = null]);
// ...
$rs = $pager->execute();
setCountQueryの最初のパラメータは有効なDoctrine_QueryオブジェクトかDQL文字列です。2番目の引数はカウンタークエリに送信されるオプションパラメータです。このパラメータを定義しないので、後でsetCountQueryParamsを呼び出して定義することができます:
$pager->setCountQueryParams([$params = array() [, $append = false]]);
このメソッドは2つのパラメータを受けとります。最初のパラメータはカウントパラメータに送信されるもので2番目のパラメータは$paramsがリストに追加されるもしくはカウントクエリパラメータがオーバーライドされるかどうかです。デフォルトのビヘイビアはリストをオーバーライドします。カウントクエリに関して最後に言うことは、カウントクエリ用のパラメータを定義しない場合、$pager->execute()の呼び出しで定義するパラメータを送り出すことができます。
カウントクエリは常にアクセスできます。これを定義して$pager->getCountQuery()を呼び出す場合、"取得(fetcher)"クエリが返されます。
Doctrine_Pagerが提供する他の機能にアクセスする必要がある場合、APIを通してアクセスできます:
// Pagerが既に実行されたかのチェックを返す
$pager->getExecuted();
// クエリ検索で見つかるアイテムの合計数を返す
$pager->getNumResults();
// 最初のページを返す(常に1)
$pager->getFirstPage();
// ページの合計数を返す
$pager->getLastPage();
// 現在のページを返す
$pager->getPage();
// 現在の新しいページを定義する(実行を再度呼び出してオフセットと値を調整する必要がある)
$pager->setPage($page);
// 次のページを返す
$pager->getNextPage();
// 前のページを返す
$pager->getPreviousPage();
// 現在のページの最初のインデックスを返す
$pager->getFirstIndice();
// 現在のページの最後のインデックスを返す
$pager->getLastIndice();
// ページ分割をする必要がある場合はtrueそうでなければfalseを返す
$pager->haveToPaginate();
// ページごとの最大数を返す
$pager->getMaxPerPage();
// ページごとのレコードの最大数を定義する(再度呼び出してオフセットと値を調整する必要がある)
$pager->setMaxPerPage($maxPerPage);
// 現在のページのアイテム数を返す
$pager->getResultsInPage();
// カウント結果をページャーにするために使われるDoctrine_Queryオブジェクトを返す
$pager->getCountQuery();
// ページャーによって使われるカウンタクエリを定義する
$pager->setCountQuery($query, $params = null);
// Doctrine_Queryカウントによって使われるパラメータを返す(パラメータが定義されていない場合$defaultParamsを返す)
$pager->getCountQueryParams($defaultParams = array());
// Doctrine_Queryカウンタによって使われるパラメータを定義する
$pager->setCountQueryParams($params = array(), $append = false);
// Doctrine_Queryオブジェクトを返す
$pager->getQuery();
// 関連するDoctrine_Pager_Range_* インスタンスを返す
$pager->getRange($rangeStyle, $options = array());
シンプルなページ分割では不十分なケースがあります。1つの例はページリンクのリストを書くときです。ページャーを越えるより強力なコントロール機能を有効にするために、レンジを作ることを可能にするページャーパッケージの小さなサブセットがあります。
現在Doctrineは2種類(2つのスタイル)のレンジ: スライディング(Doctrine_Pager_Range_Sliding)とジャンピング(Doctrine_Pager_Range_Jumping)を実装します。
スライディングページレンジスタイルは、ページレンジは現在のページでスムーズに移動します。最初と最後のページのレンジ以外、現在のページは常に真ん中です。5つのアイテムのチャンクの長さでどのように動作するのか確認してください:
Listing 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Page 1: o-------|
Page 2: |-o-----|
Page 3: |---o---|
Page 4: |---o---|
Page 5: |---o---|
Page 6: |---o---|
Page 7: |---o---|
Page 8: |---o---|
ジャンピングページレンジスタイルでは、ページリンクのレンジは常に"フレーム"の固定長の1つです: 1-5、6-10、11-15など。
Listing 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Page 1: o-------|
Page 2: |-o-----|
Page 3: |---o---|
Page 4: |-----o-|
Page 5: |-------o
Page 6: o---------|
Page 7: |-o-------|
Page 8: |---o-----|
ページレンジのスタイルの違いがわかったので、使い方を学びましょう:
$pagerRange = new Doctrine_Pager_Range_Sliding(
array(
'chunk' => 5 // チャンクの長さ
),
$pager // 以前のトピックで作り方を学んだDoctrine_Pagerオブジェクト
);
代わりに、次のコードを使うこともできます:
$pagerRange = $pager->getRange(
'Sliding',
array(
'chunk' => 5
)
);
Doctrine_Pagerの代わりにこのオブジェクトを使う利点は何でしょうか?たった1つです; 現在のページ周辺のレンジを読み取ることができることです。
次の例を見てみましょう:
// 現在のページ周辺のレンジを読み取る
// この例では、スライディングスタイルを使用しページ1にいる
$pages = $pager_range->rangeAroundPage();
// Outputs: [1][2][3][4][5]
echo '['. implode('][', $pages) .']';
レンジオブジェクトの範囲内でDoctrine_Pagerをビルドする場合、APIによってDoctrine_Pager_Rangeサブクラスのインスタンスに関連する情報を読み取ることができます:
// このPager_Rangeに関連するページャーを返す
$pager_range->getPager();
// 新しいDoctrine_Pagerを定義する(自動的なprotectされたcall _initializedメソッド)
$pager_range->setPager($pager);
// 現在のPager_Rangeに割り当てられたオプションを返す
$pager_range->getOptions();
// カスタムのDoctrine_Pager_Range実装のオフセットオプションを返す
$pager_range->getOption($option);
// 渡されたページがレンジの中にあるかチェックする
$pager_range->isInRange($page);
// 現在のページ周辺のレンジを返す
// ($pager_rangeインスタンスに関連するDoctrine_Pagerから取得)
$pager_range->rangeAroundPage();
これまで、ページ分割と現在のページ周辺のレンジを読み取る方法を学びました。ページリンク生成を含むビジネスロジックを抽象化するために、Doctrine_Pager_Layoutと呼ばれる強力なコンポーネントがあります。このコンポーネントのメインのアイディアはPHPロジックを抽象化してHTMLをDoctrineの開発者に定義させることです。
Doctrine_Pager_Layoutは必須の引数を3つ受け取ります: a Doctrine_Pagerインスタンス、Doctrine_Pager_Rangeサブクラスインスタンスとテンプレートの{%url}マスクとして割り当てられるURLを含む文字列です。ご覧の通り、Doctrine_Pager_Layoutの"変数"が2種類あります:
マスクはテンプレート内部で置き換えるものとして定義される文字列のピースです。これらは{%mask_name}として定義されオプションで定義するものもしくはDoctrine_Pager_Layoutコンポーネントによって内部で定義されたものによって置き換えられます。現在、これらは内部マスクとして利用可能です:
その名の通り、これはHTMLのスケルトンもしくはその他のスケルトンでDoctrine_Pager_Range::rangeAroundPage()サブクラスによって返されるそれぞれのページに適用されるその他のリソースです。定義できるテンプレートは3種類あります:
Doctrine_Pager_Layoutとこのコンポーネント周囲のタイプの作り方を理解したので、基本的な使い方を見てみましょう:
ページャーレイアウトの作り方は簡単です:
$pagerLayout = new Doctrine_Pager_Layout(
new Doctrine_Pager(
Doctrine_Query::create()
->from( 'User u' )
->leftJoin( 'u.Group g' )
->orderby( 'u.username ASC' ),
$currentPage,
$resultsPerPage
),
new Doctrine_Pager_Range_Sliding(array(
'chunk' => 5
)),
'http://wwww.domain.com/app/User/list/page,{%page_number}'
);
ページリンク作成のためにテンプレートを割り当てます:
$pagerLayout->setTemplate('[<a href="{%url}">{%page}</a>]');
$pagerLayout->setSelectedTemplate('[{%page}]');
// Doctrine_Pagerインスタンスを読み取る
$pager = $pagerLayout->getPager();
// ユーザーを取得する
$users = $pager->execute(); // これも可能!
// ページリンクを表示する
// 表示: [1][2][3][4][5]
// $currentPageを除いて、すべてのページでリンクがつく(この例では、ページ1)
$pagerLayout->display();
このソースを説明すると、最初の部分はページャーレイアウトのインスタンスを作成します。2番目に、すべてのページと現在のページ用のテンプレートを定義します。最後の部分では、Doctrine_Pagerオブジェクトを読み取りクエリを実行し、変数$usersを返します。最後のっ部分はオプションのマスク無しでディスプレイヤーを呼び出します。これはDoctrine_Pager_Range::rangeAroundPage()サブクラスで見つかるすべてのページにテンプレートを適用します。
ご覧の通り、内部マスク以外に他のマスクを使う必要はありません。既存のアプリケーションでUsersを検索機能を実装することを考えてみましょう。またページャーレイアウトでこの機能をサポートする必要があるとします。我々のケースを簡略化するために、検索パラメータは"search"と名付け、スーパーグローバル配列$_GETを通して受け取ります。他のページに送信できるようにするために、最初に行う必要のある変更はDoctrine_QueryオブジェクトとURLを調整することです。
ページャーレイアウトを作成する:
$pagerLayout = new Doctrine_Pager_Layout(
new Doctrine_Pager(
Doctrine_Query::create()
->from( 'User u' )
->leftJoin( 'u.Group g' )
->where('LOWER(u.username) LIKE LOWER(?)', array( '%'.$_GET['search'].'%' ) )
->orderby( 'u.username ASC' ),
$currentPage,
$resultsPerPage
),
new Doctrine_Pager_Range_Sliding(array(
'chunk' => 5
)),
'http://wwww.domain.com/app/User/list/page,{%page_number}?search={%search}'
);
コードを確認して{%search}と呼ばれる新しいマスクを追加したことに注目してください。後の段階で処理するテンプレートにこのマスクを送る必要があります。変更せずに、以前定義したように、テンプレートを割り当てます。そして、クエリの実行を変更する必要もありません。
ページリンク作成のためにテンプレートを割り当てます:
$pagerLayout->setTemplate('[<a href="{%url}">{%page}</a>]');
$pagerLayout->setSelectedTemplate('[{%page}]');
// Fetching users
$users = $pagerLayout->execute();
foreach ($users as $user) {
// ...
}
display()メソッドは作成したカスタムのマスクを定義する場所ですこのメソッドは2つのオプション引数を受け取ります: オプションマスクの1つの配列でスクリーンに出力される代わりに返される出力です。我々の場合、新しいマスクである{%search}を定義する必要があります。このマスクはスーパーグローバル配列$_GETのsearchオフセットです。このマスクはURLとして送られるので、エンコードする必要があります。カスタムのマスクは「キー => 値」のペアで定義されます。ですので必要なコードはオフセットと置き換える値で配列を定義することです:
// Displaying page links
$pagerLayout->display( array(
'search' => urlencode($_GET['search'])
) );
Doctrine_Pager_Layoutコンポーネントは定義されたリソースへのアクセサを提供します。ページャーとページャレンジを変数として定義してページャーレイアウトを送る必要はありません。これらのインスタンスは次のアクセサによって読み取られます:
// Pager_Layoutに関連するPagerを返す
$pagerLayout->getPager();
// Pager_Layoutに関連するPager_Rangeを返す
$pagerLayout->getPagerRange();
// Pager_Layoutに関連するURLマスクを返す
$pagerLayout->getUrlMask();
// Pager_Layoutに関連するテンプレートを返す
$pagerLayout->getTemplate();
// Pager_Layoutに関連する現在のページテンプレートを返す
$pagerLayout->getSelectedTemplate();
// それぞれのページに適用されるSeparatorテンプレートを定義する
$pagerLayout->setSeparatorTemplate($separatorTemplate);
// Pager_Layoutに関連する現在のページテンプレートを返す
$pagerLayout->getSeparatorTemplate();
// Pagerインスタンスを読み取らずにクエリを実行するハンディメソッド
$pagerLayout->execute($params = array(), $hydrationMode = null);
カスタムのレイアウト作成機能を作るためにDoctrine_Pager_Layoutを継承したい場合、利用可能な他のメソッドはたくさんあります。次のセクションでこれらのメソッドを見ます。
Doctrine_Pager_Layoutは本当に良い仕事をしますが、ときに十分ではないことがあります。次のようなページ分割のレイアウトを作らなければならない状況を考えてみましょう:
<< < 1 2 3 4 5 > >>
現在、生のDoctrine_Pager_Layoutでは不可能ですが、このクラスを継承して利用可能なメソッドを使えば実現可能です。基底レイアウトクラスは独自の実装を作成するために使われるメソッドを提供します。内容は次の通りです:
// $thisはDoctrine_Pager_Layoutのインスタンスを参照する
// マスクの置き換えを定義する。テンプレートを解析するとき、置き換えマスクを
// 新しいもの(もしくは値)に変換する。即座にマスクを変更できます
$this->addMaskReplacement($oldMask, $newMask, $asValue = false);
// マスク置き換えを削除する
$this->removeMaskReplacement($oldMask);
// すべてのマスク置き換えを削除する
$this->cleanMaskReplacements();
// テンプレートを解析し処理されたページの文字列を返す
$this->processPage($options = array()); // 少なくとも配列$optionsのpage_numberで必要
// Protectされたメソッドであるが、とても便利
// 渡されたページのテンプレートを解析し処理されたテンプレートを返す
$this->_parseTemplate($options = array());
// 送られたオプションによって正しいテンプレートを返すようにURLマスクを解析する
// 既に割り当てられたマスク置き換えを処理する
$this->_parseUrlTemplate($options = array());
// 与えられたページのマスク置き換えを解析する
$this->_parseReplacementsTemplate($options = array());
// 与えられたページのURLマスクを解析し処理されたURLを返す
$this->_parseUrl($options = array());
// 置き換え予定のマスクを新しいマスク/値に変更して、マスク置き換えを解析する
$this->_parseMaskReplacements($str);
Doctrine_Pager_Layoutを継承するとき便利で小さなメソッドがあるので、実装されたクラスを見てみましょう:
class PagerLayoutWithArrows extends Doctrine_Pager_Layout
{
public function display($options = array(), $return = false)
{
$pager = $this->getPager();
$str = '';
// 最初のページ
$this->addMaskReplacement('page', '«', true);
$options['page_number'] = $pager->getFirstPage();
$str .= $this->processPage($options);
// 以前のページ
$this->addMaskReplacement('page', '‹', true);
$options['page_number'] = $pager->getPreviousPage();
$str .= $this->processPage($options);
// ページの一覧
$this->removeMaskReplacement('page');
$str .= parent::display($options, true);
// 次のページ
$this->addMaskReplacement('page', '›', true);
$options['page_number'] = $pager->getNextPage();
$str .= $this->processPage($options);
// 最後のページ
$this->addMaskReplacement('page', '»', true);
$options['page_number'] = $pager->getLastPage();
$str .= $this->processPage($options);
// スクリーンに表示する代わりに値を返すことが可能
if ($return) {
return $str;
}
echo $str;
}
}
ご覧の通り、<<、<、>と>>のアイテムを手動で処理しなければなりません。生の値を設定することで{%page}マスクをオーバーライドします(生の値は3番目のパラメータをtrueとして設定します)。それからページを処理する必須情報のみを定義しこれを呼び出します。戻り値は文字列として処理されたテンプレートです。これをカスタムボタンにします。
これで全体的に異なる状況をサポートでいます。Doctrineは透過的なフレームワークですが、多くのユーザーはsymfonyと一緒に使います。Doctrine_Pagerとサブクラスはsymfonyと100%互換性がありますが、Doctrine_Pager_Layoutはsymfonyのlink_toヘルパー関数と連携するために調整が必要です。Doctrine_Pager_Layoutでこれを使うことができるようにするにはこのクラスを継承しカスタムプロセッサーを追加しなければなりません。例として(symfonyと連携させる場合)、{link_to}...{/link_to}をテンプレートプロセッサーとして使います。継承クラスとsymfonyでの使い方は次の通りです:
class sfDoctrinePagerLayout extends Doctrine_Pager_Layout
{
public function __construct($pager, $pagerRange, $urlMask)
{
sfLoader::loadHelpers(array('Url', 'Tag'));
parent::__construct($pager, $pagerRange, $urlMask);
}
protected function _parseTemplate($options = array())
{
$str = parent::_parseTemplate($options);
return preg_replace(
'/\{link_to\}(.*?)\{\/link_to\}/', link_to('$1', $this->_parseUrl($options)), $str
);
}
}
使い方:
$pagerLayout = new sfDoctrinePagerLayout(
$pager,
new Doctrine_Pager_Range_Sliding(array('chunk' => 5)),
'@hostHistoryList?page={%page_number}'
);
$pagerLayout->setTemplate('[{link_to}{%page}{/link_to}]');
Doctrineは接続からデータベースを作成したり削除する機能を提供します。これを使うためのしかけはDoctrineの接続名がデータベースの名前でなければならないことです。これが必須なのはPDOは接続するデータベースの名前を読み取るメソッドを提供しないことによります。データベースの作成と削除をできるようにするにはDoctrine自身がデータベースの名前を認識できなければなりません。
Doctrineはメインクラスで利用可能なスタティックなコンビニエンスメソッドを提供します。これらのメソッドはDoctrineの最もよく使われる複数の機能を1つのメソッドで実行します。これらのメソッドの大半はDoctrine_Taskシステムを使用します。これらのタスクはDoctrine_Cliからも実行されます。
// デバッグモードをon/offに切り替えこれがon/offであるかチェックする
Doctrine_Core::debug(true);
if (Doctrine_Core::debug() {
echo 'debugging is on';
} else {
echo 'debugging is off';
}
// Doctrineライブラリへのパスを取得する
$path = Doctrine_Core::getPath();
// Doctrineライブラリへのパスがデフォルトの位置ではない場合パスをセットする
Doctrine_Core::setPath('/path/to/doctrine/libs');
// Doctrineと連携させるためにモデルをロードする
// 発見されロードされたDoctrine_Recordsの配列を返す
$models = Doctrine_Core::loadModels('/path/to/models', Doctrine_CoreMODEL_LOADING_CONSERVATIVE); // or Doctrine_Core::MODEL_LOADING_AGGRESSIVE
print_r($models);
// ロードされたすべてのモデルの配列を取得する
$models = Doctrine_Core::getLoadedModels();
// クラスの配列を上記のメソッドに渡しDoctrine_Recordsではないものを除去する
$models = Doctrine_Core::filterInvalidModels(array('User', 'Formatter', 'Doctrine_Record'));
print_r($models); // FormatterとDoctrine_Recordが有効ではないのでarray('User')を返す
// 実際のテーブル名用のDoctrine_Connectionオブジェクトを取得する
$conn = Doctrine_Core::getConnectionByTableName('user'); // テーブル名が関連する接続オブジェクトを返す
with.
// 既存のデータベースからYAMLスキーマを生成する
Doctrine_Core::generateYamlFromDb('/path/to/dump/schema.yml', array('connection_name'), $options);
// 既存のデータベースからモデルを生成する
Doctrine_Core::generateModelsFromDb('/path/to/generate/models', array('connection_name'), $options);
// オプションとデフォルト値の配列
$options = array('packagesPrefix' => 'Package',
'packagesPath' => '',
'packagesFolderName' => 'packages',
'suffix' => '.php',
'generateBaseClasses' => true,
'baseClassesPrefix' => 'Base',
'baseClassesDirectory' => 'generated',
'baseClassName' => 'Doctrine_Record');
// YAMLスキーマからモデルを生成する
Doctrine_Core::generateModelsFromYaml('/path/to/schema.yml', '/path/to/generate/models', $options);
// 配列で提供されるテーブルを作成する
Doctrine_Core::createTablesFromArray(array('User', 'Phoneumber'));
// 既存のモデルセットからすべてのテーブルを作成する
// ディレクトリが渡されなければロードされたすべてのモデル用のSQLを生成する
Doctrine_Core::createTablesFromModels('/path/to/models');
// 既存のモデルのセットからSQLコマンドの文字列を生成する
// ディレクトリが渡されなければロードされたすべてのモデル用のSQLを生成する
Doctrine_Core::generateSqlFromModels('/path/to/models');
// 渡されたモデルの配列を作成するSQL文の配列を生成する
Doctrine_Core::generateSqlFromArray(array('User', 'Phonenumber'));
// 既存のモデルセットからYAMLスキーマを生成する
Doctrine_Core::generateYamlFromModels('/path/to/schema.yml', '/path/to/models');
// 接続用のすべてのデータベースを作成する
// 接続名の配列はオプション
Doctrine_Core::createDatabases(array('connection_name'));
// 接続に対するすべてのデータベースを削除する
// 接続名の配列はオプション
Doctrine_Core::dropDatabases(array('connection_name'));
// モデル用のすべてのデータをYAMLフィクスチャファイルにダンプする
// 2番目の引数はbool値でそれぞれのモデルに大して個別のフィクスチャファイルを生成するかどうか
// trueの場合ファイルの代わりにフォルダを指定する必要がある
Doctrine_Core::dumpData('/path/to/dump/data.yml', true);
// YAMLフィクスチャファイルからデータをロードする
// 2番目の引数はブール値でロードするときにデータを追加するかロードする前にすべてのデータを最初に削除するか
Doctrine_Core::loadData('/path/to/fixture/files', true);
// マイグレーションクラスのセット用のマイグレーション処理を実行する
$num = 5; // バージョン #5にマイグレートする
Doctrine::migration('/path/to/migrations', $num);
// 空白のマイグレーションクラスのテンプレートを生成する
Doctrine_Core::generateMigrationClass('ClassName', '/path/to/migrations');
// 既存のデータベース用のすべてのマイグレーションクラスを生成する
Doctrine_Core::generateMigrationsFromDb('/path/to/migrations');
// 既存のモデルのセット用のすべてのマイグレーションクラスを生成する
// 2番目の引数はloadModels()を使用して既にモデルをロードしている場合のオプション
Doctrine_Core::generateMigrationsFromModels('/path/to/migrations', '/path/to/models');
// モデル用のDoctrine_Tableインスタンスを取得する
$userTable = Doctrine_Core::getTable('User');
// Doctrineを単独のPHPファイルにコンパイルする
$drivers = array('mysql'); //コンパイルされたバージョンに含めたいドライバの配列を指定する
Doctrine_Core::compile('/path/to/write/compiled/doctrine', $drivers);
// デバッグ用にDoctrineオブジェクトをダンプする
$conn = Doctrine_Manager::connection();
Doctrine_Core::dump($conn);
タスクはコアのコンビニエンスメソッドを搭載するクラスです。必須の引数を設定することでタスクを簡単に実行できます。これらのタスクはDoctrineコマンドラインインターフェイスで直接使われます。
BuildAll
BuildAllLoad
BuildAllReload
Compile
CreateDb
CreateTables
Dql
DropDb
DumpData
Exception
GenerateMigration
GenerateMigrationsDb
GenerateMigrationsModels
GenerateModelsDb
GenerateModelsYaml
GenerateSql
GenerateYamlDb
GenerateYamlModels
LoadData
Migrate
RebuildDb
独自スクリプトでDoctrine Tasksを単独で実行する方法は下記の通りです。
Doctrine_Cliはタスクのコレクションで開発とテストの手助けをしてくれます。このマニュアルの典型例に関して、必要なタスクを実行するためにPHPスクリプトをセットアップします。このcliツールはこれらのタスクのためにそのまま使えることを目的としています。
Doctrineの実装を管理するために利用できるタスクの一覧は下記の通りです。
$ ./doctrine
Doctrine Command Line Interface
./doctrine build-all
./doctrine build-all-load
./doctrine build-all-reload
./doctrine compile
./doctrine create-db
./doctrine create-tables
./doctrine dql
./doctrine drop-db
./doctrine dump-data
./doctrine generate-migration
./doctrine generate-migrations-db
./doctrine generate-migrations-models
./doctrine generate-models-db
./doctrine generate-models-yaml
./doctrine generate-sql
./doctrine generate-yaml-db
./doctrine generate-yaml-models
./doctrine load-data
./doctrine migrate
./doctrine rebuild-db
CLI用のタスクは独立しており単独で使うことができます。下記のコードは例です。
$task = new Doctrine_Task_GenerateModelsFromYaml();
$args = array('yaml_schema_path' => '/path/to/schema',
'models_path' => '/path/to/models');
$task->setArguments($args);
try {
if ($task->validate()) {
$task->execute();
}
} catch (Exception $e) {
throw new Doctrine_Exception($e->getMessage());
}
"doctrine"という名前のファイルを実行可能にします。
#!/usr/bin/env php
[php]
chdir(dirname(__FILE__));
include('doctrine.php');
?>
Doctrine_Cliを実装する実際の"doctrine.php"という名前のPHPファイルは次の通りです。
// Doctrineの設定/セットアップ、接続、モデルなどを含める
// Doctrine Cliを設定する
// 通常cliタスクの引数がありますがここで設定すれば引数は自動的に入力されスクリプト実行時に入力する必要がなくなる
$config = array('data_fixtures_path' => '/path/to/data/fixtures',
'models_path' => '/path/to/models',
'migrations_path' => '/path/to/migrations',
'sql_path' => '/path/to/data/sql',
'yaml_schema_path' => '/path/to/schema');
$cli = new Doctrine_Cli($config);
$cli->run($_SERVER['argv']);
これで次のようにコマンドを実行できます。
./doctrine generate-models-yaml
./doctrine create-tables
http://www.doctrine-project.org/download からもしくはsvnリポジトリから特別なサンドボックスをインストールできます。
svn co http://www.doctrine-project.org/svn/branches/0.11 doctrine
cd doctrine/tools/sandbox
chmod 0777 doctrine
./doctrine
上記のステップによってサンドボックスのcliが実行できるようになります。引数無しで./doctrineコマンドを実行すると利用可能なすべてのcliタスクのインデックスが表示されます。
この章で検討したこれらのユーティリティが役に立つことを願います。Unit Testingを使用することでDoctrineの安定性を維持し回帰を避ける方法を検討します。